{
  "openapi": "3.0.3",
  "info": {
    "title": "KLARA Public API",
    "description": "REST API for integrating with KLARA business software.\n\nSee developer.klara.ch for guides, authentication and getting started.\n\n**Important note:** Effective November 15th, 2024, HTTP/1.0 is no longer supported. Use HTTP/1.1 or HTTP/2.",
    "version": "0.0.1"
  },
  "servers": [
    {
      "url": "https://api.klara.ch",
      "description": "Production. The only environment available to customers."
    }
  ],
  "tags": [
    {
      "name": "Authentication",
      "description": "KLARA Authentication flow"
    },
    {
      "name": "Article",
      "description": "KLARA Article data"
    },
    {
      "name": "Customer",
      "description": "KLARA CRM Contact data"
    },
    {
      "name": "Location",
      "description": "Geographical details"
    },
    {
      "name": "Klara authentication generic"
    },
    {
      "name": "Subscription",
      "description": "Subscription management. Unlock features for KLARA users."
    },
    {
      "name": "Company",
      "description": "Find/Create/Update a KLARA business company"
    },
    {
      "name": "Individual",
      "description": "Operations related to individual companies"
    },
    {
      "name": "Accounting Interface",
      "description": "External accounting"
    },
    {
      "name": "Accounting",
      "description": "Klara Accounting public API (v1) — bookings and supporting master data. Served under /core/v1."
    },
    {
      "name": "Payroll",
      "description": "Klara Payroll public API (v1) — employee salary items and payslips. Served under /core/v1."
    },
    {
      "name": "Company documents",
      "description": "Upload and manage documents attached to a company (e.g. salary certificates, work permits, contracts)."
    },
    {
      "name": "Finance",
      "description": "KLARA Finance public API (v1) — invoices, orders, order documents, order numbering configurations and company bank accounts. Served under /core/v1."
    },
    {
      "name": "Company general"
    }
  ],
  "paths": {
    "/core/latest/article-categories": {
      "get": {
        "tags": [
          "Article"
        ],
        "summary": "Get all categories",
        "parameters": [
          {
            "name": "active-status",
            "in": "query",
            "description": "Active status",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "keyword",
            "in": "query",
            "description": "Name",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Limit filters returned",
            "schema": {
              "format": "int32",
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "name": "Accept-Language",
            "in": "header",
            "description": "Language code is used for filtering by the keyword with multilingual",
            "schema": {
              "type": "string"
            },
            "example": "en"
          }
        ],
        "responses": {
          "200": {
            "description": "Return successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/ArticleCategory"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Data invalid",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "401": {
            "description": "No Authorization header found or invalid token"
          },
          "403": {
            "description": "The current user is not allowed to access this company data",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "429": {
            "description": "API rate limit exceeded"
          }
        },
        "security": [
          {
            "apiKeyAuth": []
          },
          {
            "bearerAuth": []
          }
        ]
      },
      "post": {
        "tags": [
          "Article"
        ],
        "summary": "Create a new category",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ArticleCategory"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Category created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ArticleCategory"
                }
              }
            }
          },
          "400": {
            "description": "Data invalid",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "401": {
            "description": "No Authorization header found or invalid token"
          },
          "403": {
            "description": "The current user is not allowed to access this company data",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "429": {
            "description": "API rate limit exceeded"
          }
        },
        "security": [
          {
            "apiKeyAuth": []
          },
          {
            "bearerAuth": []
          }
        ]
      }
    },
    "/core/latest/article-categories/{category-id}": {
      "get": {
        "tags": [
          "Article"
        ],
        "summary": "Get category by id",
        "parameters": [
          {
            "name": "category-id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Return successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ArticleCategory"
                }
              }
            }
          },
          "401": {
            "description": "No Authorization header found or invalid token"
          },
          "403": {
            "description": "The current user is not allowed to access this company data",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found"
          },
          "429": {
            "description": "API rate limit exceeded"
          }
        },
        "security": [
          {
            "apiKeyAuth": []
          },
          {
            "bearerAuth": []
          }
        ]
      },
      "put": {
        "tags": [
          "Article"
        ],
        "summary": "Update category by Id",
        "parameters": [
          {
            "name": "category-id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ArticleCategory"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Updated successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ArticleCategory"
                }
              }
            }
          },
          "400": {
            "description": "Data invalid",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "401": {
            "description": "No Authorization header found or invalid token"
          },
          "403": {
            "description": "The current user is not allowed to access this company data",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found"
          },
          "429": {
            "description": "API rate limit exceeded"
          }
        },
        "security": [
          {
            "apiKeyAuth": []
          },
          {
            "bearerAuth": []
          }
        ]
      },
      "delete": {
        "tags": [
          "Article"
        ],
        "summary": "Delete category by Id",
        "parameters": [
          {
            "name": "category-id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Deleted successfully"
          },
          "400": {
            "description": "Data invalid",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "401": {
            "description": "No Authorization header found or invalid token"
          },
          "403": {
            "description": "The current user is not allowed to access this company data",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found"
          },
          "429": {
            "description": "API rate limit exceeded"
          }
        },
        "security": [
          {
            "apiKeyAuth": []
          },
          {
            "bearerAuth": []
          }
        ]
      }
    },
    "/core/latest/article-categories/{category-id}/assign-to-articles": {
      "post": {
        "tags": [
          "Article"
        ],
        "summary": "Assign category to articles",
        "description": "Assign the specified <b>article category</b> to multiple <b>articles</b> for usage in Online Booking, Online shop, and Point of sale.<br /><b>Only the articles entered in the request body</b> will have the specified <b>article category</b> added to their respective filters.<br />Other articles will not be affected",
        "parameters": [
          {
            "name": "category-id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CategoryAssigningGroup"
              }
            }
          }
        },
        "responses": {
          "204": {
            "description": "Assigned successfully"
          },
          "400": {
            "description": "Data invalid",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "401": {
            "description": "No Authorization header found or invalid token"
          },
          "403": {
            "description": "The current user is not allowed to access this company data",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found"
          },
          "429": {
            "description": "API rate limit exceeded"
          }
        },
        "security": [
          {
            "apiKeyAuth": []
          },
          {
            "bearerAuth": []
          }
        ]
      }
    },
    "/core/latest/article-filters": {
      "get": {
        "tags": [
          "Article"
        ],
        "summary": "Search article filters",
        "parameters": [
          {
            "name": "active-status",
            "in": "query",
            "description": "Active status",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "keyword",
            "in": "query",
            "description": "Name",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Limit filters returned",
            "schema": {
              "format": "int32",
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "name": "Accept-Language",
            "in": "header",
            "description": "Language code is used for filtering by the keyword with multilingual",
            "schema": {
              "type": "string"
            },
            "example": "en"
          }
        ],
        "responses": {
          "200": {
            "description": "Filters",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/ArticleFilter"
                  }
                }
              }
            }
          },
          "401": {
            "description": "No Authorization header found or invalid token"
          },
          "403": {
            "description": "The current user is not allowed to access this company data",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "429": {
            "description": "API rate limit exceeded"
          }
        },
        "security": [
          {
            "apiKeyAuth": []
          },
          {
            "bearerAuth": []
          }
        ]
      },
      "post": {
        "tags": [
          "Article"
        ],
        "summary": "Create a article filter",
        "requestBody": {
          "description": "Filter data",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ArticleFilter"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Filter created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ArticleFilter"
                }
              }
            }
          },
          "400": {
            "description": "Data invalid",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "401": {
            "description": "No Authorization header found or invalid token"
          },
          "403": {
            "description": "The current user is not allowed to access this company data",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "429": {
            "description": "API rate limit exceeded"
          }
        },
        "security": [
          {
            "apiKeyAuth": []
          },
          {
            "bearerAuth": []
          }
        ]
      }
    },
    "/core/latest/article-filters/{filter-id}": {
      "get": {
        "tags": [
          "Article"
        ],
        "summary": "Get article filter by id",
        "parameters": [
          {
            "name": "filter-id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Filter",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ArticleFilter"
                }
              }
            }
          },
          "401": {
            "description": "No Authorization header found or invalid token"
          },
          "403": {
            "description": "The current user is not allowed to access this company data",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found"
          },
          "429": {
            "description": "API rate limit exceeded"
          }
        },
        "security": [
          {
            "apiKeyAuth": []
          },
          {
            "bearerAuth": []
          }
        ]
      },
      "put": {
        "tags": [
          "Article"
        ],
        "summary": "Update article filter by id",
        "parameters": [
          {
            "name": "filter-id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "description": "Filter data",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ArticleFilter"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Update successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ArticleFilter"
                }
              }
            }
          },
          "400": {
            "description": "Data invalid",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "401": {
            "description": "No Authorization header found or invalid token"
          },
          "403": {
            "description": "The current user is not allowed to access this company data",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found"
          },
          "429": {
            "description": "API rate limit exceeded"
          }
        },
        "security": [
          {
            "apiKeyAuth": []
          },
          {
            "bearerAuth": []
          }
        ]
      },
      "delete": {
        "tags": [
          "Article"
        ],
        "summary": "Delete article filter by id",
        "description": "This filter will be removed from all articles",
        "parameters": [
          {
            "name": "filter-id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Delete successfully"
          },
          "401": {
            "description": "No Authorization header found or invalid token"
          },
          "403": {
            "description": "The current user is not allowed to access this company data",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found"
          },
          "429": {
            "description": "API rate limit exceeded"
          }
        },
        "security": [
          {
            "apiKeyAuth": []
          },
          {
            "bearerAuth": []
          }
        ]
      }
    },
    "/core/latest/article-filters/{filter-id}/assign-to-articles": {
      "post": {
        "tags": [
          "Article"
        ],
        "summary": "Assign filter to articles",
        "description": "Assign the specified <b>article filter</b> to multiple <b>articles</b> for usage in Online Booking, Online shop, and Point of sale.<br /><b>Only the articles entered in the request body</b> will have the specified <b>article filter</b> added to their respective filters.<br />Other articles will not be affected",
        "parameters": [
          {
            "name": "filter-id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "description": "Article ids",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/FilterAssigningGroup"
              }
            }
          },
          "required": true
        },
        "responses": {
          "204": {
            "description": "Successfully"
          },
          "400": {
            "description": "Data invalid",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "401": {
            "description": "No Authorization header found or invalid token"
          },
          "403": {
            "description": "The current user is not allowed to access this company data",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found"
          },
          "429": {
            "description": "API rate limit exceeded"
          }
        },
        "security": [
          {
            "apiKeyAuth": []
          },
          {
            "bearerAuth": []
          }
        ]
      }
    },
    "/core/latest/articles": {
      "get": {
        "tags": [
          "Article"
        ],
        "summary": "Returns article list of a company",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "description": "Define the limit of the article list that this API returns.<br />For example, if a company have 20 articles in total, and this <b>limit</b> parameter is 5, and the <b>offset</b> parameter is 0,<br />then this API will return article list containing the first 5 articles<br />If not set, then default value of 48 is used",
            "schema": {
              "format": "int32",
              "default": "48",
              "maximum": 1000,
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "name": "offset",
            "in": "query",
            "description": "Define which position to start getting article list.<br />For example, if a company have 20 articles in total, and this <b>offset</b> parameter is 5,<br />then this API will return article list from the 5th article.<br />If not set, then default value of 0 is used",
            "schema": {
              "format": "int32",
              "default": "0",
              "minimum": 0,
              "type": "integer"
            }
          },
          {
            "name": "product-type",
            "in": "query",
            "description": "Filter articles with this product type.",
            "schema": {
              "$ref": "#/components/schemas/ProductType"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Articles",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Article"
                  }
                }
              }
            }
          },
          "401": {
            "description": "No Authorization header found or invalid token"
          },
          "403": {
            "description": "The current user is not allowed to access this company data",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "429": {
            "description": "API rate limit exceeded"
          }
        },
        "security": [
          {
            "apiKeyAuth": []
          },
          {
            "bearerAuth": []
          }
        ]
      },
      "post": {
        "tags": [
          "Article"
        ],
        "summary": "Create a new article",
        "requestBody": {
          "description": "The article object with the information that needs to be created",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Article"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Article created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Article"
                }
              }
            }
          },
          "400": {
            "description": "Data invalid",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "401": {
            "description": "No Authorization header found or invalid token"
          },
          "403": {
            "description": "The current user is not allowed to access this company data",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "429": {
            "description": "API rate limit exceeded"
          }
        },
        "security": [
          {
            "apiKeyAuth": []
          },
          {
            "bearerAuth": []
          }
        ]
      }
    },
    "/core/latest/articles/{article-id}": {
      "get": {
        "tags": [
          "Article"
        ],
        "summary": "Get article by article id",
        "parameters": [
          {
            "name": "article-id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Found article",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Article"
                }
              }
            }
          },
          "401": {
            "description": "No Authorization header found or invalid token"
          },
          "403": {
            "description": "The current user is not allowed to access this company data",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "429": {
            "description": "API rate limit exceeded"
          }
        },
        "security": [
          {
            "apiKeyAuth": []
          },
          {
            "bearerAuth": []
          }
        ]
      },
      "put": {
        "tags": [
          "Article"
        ],
        "summary": "Update an existing article",
        "parameters": [
          {
            "name": "article-id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "description": "The article object with the information that needs to be updated",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Article"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Article updated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Article"
                }
              }
            }
          },
          "400": {
            "description": "Data invalid",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "401": {
            "description": "No Authorization header found or invalid token"
          },
          "403": {
            "description": "The current user is not allowed to access this company data",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "429": {
            "description": "API rate limit exceeded"
          }
        },
        "security": [
          {
            "apiKeyAuth": []
          },
          {
            "bearerAuth": []
          }
        ]
      },
      "delete": {
        "tags": [
          "Article"
        ],
        "summary": "Delete an article",
        "parameters": [
          {
            "name": "article-id",
            "in": "path",
            "description": "Id of the article to be deleted",
            "required": true,
            "schema": {
              "type": "string",
              "example": "1"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Article deleted by given article id"
          },
          "400": {
            "description": "Data invalid",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "401": {
            "description": "No Authorization header found or invalid token"
          },
          "403": {
            "description": "The current user is not allowed to access this company data",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "429": {
            "description": "API rate limit exceeded"
          },
          "500": {
            "description": "Something went wrong on our side while processing the request. Please kindly contact our support."
          }
        },
        "security": [
          {
            "apiKeyAuth": []
          },
          {
            "bearerAuth": []
          }
        ]
      }
    },
    "/core/latest/articles/{article-id}/article-set-items": {
      "get": {
        "tags": [
          "Article"
        ],
        "summary": "Get list of items from article set",
        "parameters": [
          {
            "name": "article-id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Return successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/PublicApiArticleSetItem"
                  }
                }
              }
            }
          },
          "401": {
            "description": "No Authorization header found or invalid token"
          },
          "403": {
            "description": "The current user is not allowed to access this company data",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "429": {
            "description": "API rate limit exceeded"
          }
        },
        "security": [
          {
            "apiKeyAuth": []
          },
          {
            "bearerAuth": []
          }
        ]
      }
    },
    "/core/latest/articles/{article-id}/images": {
      "post": {
        "tags": [
          "Article"
        ],
        "summary": "Add an image to an article",
        "description": "Image size limit: 5MB<br />Supported image type: PNG, JPG, JPEG",
        "parameters": [
          {
            "name": "article-id",
            "in": "path",
            "description": "Id of the article to add an image to",
            "required": true,
            "schema": {
              "type": "string",
              "example": "1"
            }
          }
        ],
        "requestBody": {
          "content": {
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/BinaryFile"
              },
              "encoding": {
                "file": {
                  "contentType": "application/octet-stream"
                }
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Image added for article",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ArticleImage"
                }
              }
            }
          },
          "400": {
            "description": "Data invalid",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "401": {
            "description": "No Authorization header found or invalid token"
          },
          "403": {
            "description": "The current user is not allowed to access this company data",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "415": {
            "description": "Unsupported Media Type"
          },
          "429": {
            "description": "API rate limit exceeded"
          },
          "500": {
            "description": "Something went wrong on our side while processing the request. Please kindly contact our support."
          }
        },
        "security": [
          {
            "apiKeyAuth": []
          },
          {
            "bearerAuth": []
          }
        ]
      }
    },
    "/core/latest/articles/{article-id}/images/{image-id}": {
      "get": {
        "tags": [
          "Article"
        ],
        "summary": "Get the content of an article image",
        "parameters": [
          {
            "name": "article-id",
            "in": "path",
            "description": "Id of the article to get an image from",
            "required": true,
            "schema": {
              "type": "string",
              "example": "1"
            }
          },
          {
            "name": "image-id",
            "in": "path",
            "description": "Id of the image to get the content from",
            "required": true,
            "schema": {
              "type": "string",
              "example": "1"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Content of an article image",
            "content": {
              "application/octet-stream": {}
            }
          },
          "401": {
            "description": "No Authorization header found or invalid token"
          },
          "403": {
            "description": "The current user is not allowed to access this company data",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "404": {
            "description": "The image of the article or the article itself could not be found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "429": {
            "description": "API rate limit exceeded"
          },
          "500": {
            "description": "Something went wrong on our side while processing the request. Please kindly contact our support."
          }
        },
        "security": [
          {
            "apiKeyAuth": []
          },
          {
            "bearerAuth": []
          }
        ]
      },
      "put": {
        "tags": [
          "Article"
        ],
        "summary": "Update an article image",
        "description": "Image size limit: 5MB<br />Supported image type: PNG, JPG, JPEG",
        "parameters": [
          {
            "name": "article-id",
            "in": "path",
            "description": "Id of the article to update an image",
            "required": true,
            "schema": {
              "type": "string",
              "example": "1"
            }
          },
          {
            "name": "image-id",
            "in": "path",
            "description": "Id of the image to update",
            "required": true,
            "schema": {
              "type": "string",
              "example": "1"
            }
          }
        ],
        "requestBody": {
          "content": {
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/BinaryFile"
              },
              "encoding": {
                "file": {
                  "contentType": "application/octet-stream"
                }
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Image updated for article",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ArticleImage"
                }
              }
            }
          },
          "400": {
            "description": "Data invalid",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "401": {
            "description": "No Authorization header found or invalid token"
          },
          "403": {
            "description": "The current user is not allowed to access this company data",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "404": {
            "description": "The image of the article or the article itself could not be found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "415": {
            "description": "Unsupported Media Type"
          },
          "429": {
            "description": "API rate limit exceeded"
          },
          "500": {
            "description": "Something went wrong on our side while processing the request. Please kindly contact our support."
          }
        },
        "security": [
          {
            "apiKeyAuth": []
          },
          {
            "bearerAuth": []
          }
        ]
      },
      "delete": {
        "tags": [
          "Article"
        ],
        "summary": "Delete an article image",
        "parameters": [
          {
            "name": "article-id",
            "in": "path",
            "description": "Id of the article to delete an image from",
            "required": true,
            "schema": {
              "type": "string",
              "example": "1"
            }
          },
          {
            "name": "image-id",
            "in": "path",
            "description": "Id of the image to delete",
            "required": true,
            "schema": {
              "type": "string",
              "example": "1"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Image deleted for given article"
          },
          "400": {
            "description": "Data invalid",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "401": {
            "description": "No Authorization header found or invalid token"
          },
          "403": {
            "description": "The current user is not allowed to access this company data",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "404": {
            "description": "The image of the article or the article itself could not be found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "429": {
            "description": "API rate limit exceeded"
          },
          "500": {
            "description": "Something went wrong on our side while processing the request. Please kindly contact our support."
          }
        },
        "security": [
          {
            "apiKeyAuth": []
          },
          {
            "bearerAuth": []
          }
        ]
      }
    },
    "/core/latest/articles/{article-id}/variants": {
      "get": {
        "tags": [
          "Article"
        ],
        "summary": "Get variants of an article",
        "parameters": [
          {
            "name": "article-id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Found variants",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Variant"
                  }
                }
              }
            }
          },
          "401": {
            "description": "No Authorization header found or invalid token"
          },
          "403": {
            "description": "The current user is not allowed to access this company data",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "429": {
            "description": "API rate limit exceeded"
          }
        },
        "security": [
          {
            "apiKeyAuth": []
          },
          {
            "bearerAuth": []
          }
        ]
      }
    },
    "/core/latest/articles/{article-id}/variants/{variant-id}": {
      "get": {
        "tags": [
          "Article"
        ],
        "summary": "Get variants of an article with id",
        "parameters": [
          {
            "name": "article-id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "variant-id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Found article variant",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Variant"
                }
              }
            }
          },
          "401": {
            "description": "No Authorization header found or invalid token"
          },
          "403": {
            "description": "The current user is not allowed to access this company data",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "429": {
            "description": "API rate limit exceeded"
          }
        },
        "security": [
          {
            "apiKeyAuth": []
          },
          {
            "bearerAuth": []
          }
        ]
      }
    },
    "/core/latest/articles/article-and-variants": {
      "get": {
        "tags": [
          "Article"
        ],
        "summary": "Returns list of articles and treat a variant combination same as an article",
        "parameters": [
          {
            "name": "include-quantity",
            "in": "query",
            "description": "flag to include quantity in the result.",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Define the limit of the article list that this API returns.<br />For example, if a company have 20 articles in total, and this <b>limit</b> parameter is 5, and the <b>offset</b> parameter is 0,<br />then this API will return article list containing the first 5 articles<br />If not set, then default value of 48 is used",
            "schema": {
              "format": "int32",
              "default": "48",
              "maximum": 1000,
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "name": "offset",
            "in": "query",
            "description": "Define which position to start getting article list.<br />For example, if a company have 20 articles in total, and this <b>offset</b> parameter is 5,<br />then this API will return article list from the 5th article.<br />If not set, then default value of 0 is used",
            "schema": {
              "format": "int32",
              "default": "0",
              "minimum": 0,
              "type": "integer"
            }
          },
          {
            "name": "sell-in-booking",
            "in": "query",
            "description": "flag to define sellable article for booking.",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "sell-in-online-shop",
            "in": "query",
            "description": "flag to query articles that are sold in online shop.",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "use-pos",
            "in": "query",
            "description": "flag to define article that are using in POS.",
            "schema": {
              "type": "boolean"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "List of article and variant",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/ArticleAndVariant"
                  }
                }
              }
            }
          },
          "401": {
            "description": "No Authorization header found or invalid token"
          },
          "403": {
            "description": "The current user is not allowed to access this company data",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "429": {
            "description": "API rate limit exceeded"
          }
        },
        "security": [
          {
            "apiKeyAuth": []
          },
          {
            "bearerAuth": []
          }
        ]
      }
    },
    "/core/latest/articles/article-numbers": {
      "get": {
        "tags": [
          "Article"
        ],
        "summary": "Find articles by article numbers",
        "description": "Batch-resolve a list of article numbers to their priced article rows of the caller's company. Returns each row enriched with the price valid on `price-date` and the appropriate VAT rate. Unknown article numbers are silently skipped (returned list contains only matching rows). Requires permission `ARTICLE_READ_ONLY`.",
        "parameters": [
          {
            "name": "article-numbers",
            "in": "query",
            "description": "Article numbers to look up. Repeat the parameter for each value (e.g. `?article-numbers=ART-001&article-numbers=ART-002`). At most 100 entries; each entry up to 64 characters.",
            "schema": {
              "maxItems": 100,
              "type": "array",
              "example": "ART-001"
            }
          },
          {
            "name": "export-vat",
            "in": "query",
            "description": "If `true`, return ABROAD (export) VAT rate; otherwise NORMAL. Defaults to false.",
            "schema": {
              "default": "false",
              "type": "boolean"
            }
          },
          {
            "name": "price-date",
            "in": "query",
            "description": "Date on which prices are evaluated. Format: yyyy-MM-dd. Defaults to today when omitted.",
            "schema": {
              "format": "date",
              "type": "string",
              "example": "2026-06-01"
            }
          },
          {
            "name": "should-validate-vat",
            "in": "query",
            "description": "If `true`, cross-validate each row's VAT code against the company's VAT setup on `price-date`. Defaults to false.",
            "schema": {
              "default": "false",
              "type": "boolean"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Matching articles",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/ArticleAndVariant"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Data invalid",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "401": {
            "description": "No Authorization header found or invalid token"
          },
          "403": {
            "description": "The current user is not allowed to access this company data",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "429": {
            "description": "API rate limit exceeded"
          },
          "500": {
            "description": "Something went wrong on our side while processing the request. Please kindly contact our support."
          }
        },
        "security": [
          {
            "apiKeyAuth": []
          },
          {
            "bearerAuth": []
          }
        ]
      }
    },
    "/core/latest/articles/bulk": {
      "post": {
        "tags": [
          "Article"
        ],
        "summary": "Create articles",
        "requestBody": {
          "description": "The list of articles",
          "content": {
            "application/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/Article"
                }
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Article created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BulkArticleCreatingResponse"
                }
              }
            }
          },
          "401": {
            "description": "No Authorization header found or invalid token"
          },
          "403": {
            "description": "The current user is not allowed to access this company data",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "429": {
            "description": "API rate limit exceeded"
          }
        },
        "security": [
          {
            "apiKeyAuth": []
          },
          {
            "bearerAuth": []
          }
        ]
      }
    },
    "/core/latest/articles/search": {
      "get": {
        "tags": [
          "Article"
        ],
        "summary": "Search articles by keyword",
        "description": "Free-text search across sellable articles (and their variants) of the caller's company. Matches by name, article number, barcode, variant number and set-header name. Returns each row enriched with the price valid on `price-date` and the appropriate VAT rate. Requires permission `ARTICLE_READ_ONLY`.",
        "parameters": [
          {
            "name": "export-vat",
            "in": "query",
            "description": "If `true`, return ABROAD (export) VAT rate; otherwise NORMAL.",
            "schema": {
              "default": "false",
              "type": "boolean"
            }
          },
          {
            "name": "keyword",
            "in": "query",
            "description": "Free-text search keyword. Trimmed; empty/missing returns the first page unfiltered.",
            "schema": {
              "maxLength": 256,
              "type": "string",
              "example": "paper"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Page size (1–100).",
            "schema": {
              "default": "50",
              "maximum": 100,
              "minimum": 1,
              "type": "integer",
              "example": 50
            }
          },
          {
            "name": "offset",
            "in": "query",
            "description": "0-based pagination offset.",
            "schema": {
              "default": "0",
              "minimum": 0,
              "type": "integer",
              "example": 0
            }
          },
          {
            "name": "price-date",
            "in": "query",
            "description": "Date on which prices are evaluated. Format: yyyy-MM-dd. Defaults to today when omitted.",
            "schema": {
              "format": "date",
              "type": "string",
              "example": "2026-06-01"
            }
          },
          {
            "name": "should-validate-vat",
            "in": "query",
            "description": "If `true`, cross-validate each row's VAT code against the company's VAT setup on `price-date`.",
            "schema": {
              "default": "false",
              "type": "boolean"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Matching articles",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/ArticleAndVariant"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Data invalid",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "401": {
            "description": "No Authorization header found or invalid token"
          },
          "403": {
            "description": "The current user is not allowed to access this company data",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "429": {
            "description": "API rate limit exceeded"
          },
          "500": {
            "description": "Something went wrong on our side while processing the request. Please kindly contact our support."
          }
        },
        "security": [
          {
            "apiKeyAuth": []
          },
          {
            "bearerAuth": []
          }
        ]
      }
    },
    "/core/latest/cities/{city-id}": {
      "get": {
        "tags": [
          "Location"
        ],
        "summary": "Returns city details",
        "description": "Returns a City details with given id.",
        "parameters": [
          {
            "name": "city-id",
            "in": "path",
            "description": "City id",
            "required": true,
            "schema": {
              "type": "string",
              "example": "1"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Found city",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/City"
                }
              }
            }
          },
          "401": {
            "description": "No Authorization header found or invalid token"
          },
          "404": {
            "description": "Resource not found"
          },
          "429": {
            "description": "API rate limit exceeded"
          }
        },
        "security": [
          {
            "apiKeyAuth": []
          },
          {
            "bearerAuth": []
          }
        ]
      }
    },
    "/core/latest/companies/{company-id}/documents": {
      "post": {
        "tags": [
          "Company documents"
        ],
        "summary": "Upload a document for a company",
        "description": "Uploads a single file under one of a fixed set of document categories. The tenant is derived from the bearer token; only the authenticated company's id may be used in the path. Maximum file size: 25 MB. For category LIABILITY_UPLOAD the downstream service additionally triggers asynchronous AI analysis (the upload response is returned regardless of the AI outcome). Required caller roles (enforced by the API gateway): COMPANY_ADMINISTRATOR, TRUSTED_USER or CUSTOMER_RELATIONSHIP_MANAGER.<br/><br/><strong>Important:</strong> When uploading documents as part of the <strong>create booking</strong> functionality only the <code>LIABILITY_UPLOAD</code> category is allowed (the documents are automatically moved to <code>LIABILITIES</code> when the booking is created successfully via <code>POST /core/v1/bookings</code>). The GUI implementation of booking creation must therefore always pass <code>LIABILITY_UPLOAD</code> as the <code>category</code> value in the request body.",
        "operationId": "uploadCompanyDocument",
        "parameters": [
          {
            "name": "company-id",
            "in": "path",
            "description": "Identifier of the company that owns the document. Must match the company id carried by the bearer token, otherwise the request is rejected with 403.",
            "required": true,
            "schema": {
              "format": "int64",
              "type": "integer",
              "nullable": false
            }
          }
        ],
        "requestBody": {
          "description": "Multipart body with two parts: 'category' (text) and 'file' (binary, ≤ 25 MB).",
          "content": {
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/CompanyDocumentUploadForm"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Document successfully uploaded.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "documentId": {
                      "description": "Identifier of the stored document, assigned by the document service.",
                      "type": "string",
                      "example": "550e8400-e29b-41d4-a716-446655440000"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Data invalid",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage1"
                }
              }
            }
          },
          "401": {
            "description": "No Authorization header found or invalid token"
          },
          "403": {
            "description": "The current user is not allowed to access this company data",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage1"
                }
              }
            }
          },
          "413": {
            "description": "Uploaded file exceeds the 25 MB limit.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage1"
                }
              }
            }
          },
          "415": {
            "description": "Unsupported Media Type"
          },
          "429": {
            "description": "API rate limit exceeded"
          },
          "500": {
            "description": "Something went wrong on our side while processing the request. Please kindly contact our support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage1"
                }
              }
            }
          }
        },
        "security": [
          {
            "apiKeyAuth": []
          },
          {
            "bearerAuth": []
          }
        ]
      }
    },
    "/core/latest/company-configuration/including-vat": {
      "get": {
        "tags": [
          "Company general"
        ],
        "summary": "Get the VAT inclusion setting for the authenticated company.",
        "description": "Returns whether invoice amounts for the company resolved from the bearer JWT are displayed and calculated <em>including</em> VAT (<code>includingVat: true</code>) or <em>excluding</em> VAT (<code>includingVat: false</code>). Use this value before creating or displaying invoices to apply the correct pricing model. When no configuration record exists for the company, the endpoint returns <code>false</code> (excluding VAT) as the default. The caller must hold the <code>FINANCE</code> permission on the target company.",
        "responses": {
          "200": {
            "description": "VAT inclusion setting for the authenticated company.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CompanyConfigurationIncludingVatResult"
                }
              }
            }
          },
          "401": {
            "description": "No Authorization header found or invalid token"
          },
          "403": {
            "description": "The current user is not allowed to access this company data",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "429": {
            "description": "API rate limit exceeded"
          },
          "500": {
            "description": "Something went wrong on our side while processing the request. Please kindly contact our support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          }
        },
        "security": [
          {
            "apiKeyAuth": []
          },
          {
            "bearerAuth": []
          }
        ]
      }
    },
    "/core/latest/company-vats": {
      "get": {
        "tags": [
          "Company general"
        ],
        "summary": "Returns vat list of a company",
        "parameters": [
          {
            "name": "Accept-Language",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Company vats",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/CompanyVAT"
                  }
                }
              }
            }
          },
          "401": {
            "description": "No Authorization header found or invalid token"
          },
          "403": {
            "description": "The current user is not allowed to access this company data",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          }
        },
        "security": [
          {
            "apiKeyAuth": []
          },
          {
            "bearerAuth": []
          }
        ]
      }
    },
    "/core/latest/customers": {
      "get": {
        "tags": [
          "Customer"
        ],
        "summary": "Returns all customers of a company",
        "responses": {
          "200": {
            "description": "Customers",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Customer"
                  }
                }
              }
            }
          },
          "401": {
            "description": "No Authorization header found or invalid token"
          },
          "403": {
            "description": "The current user is not allowed to access this company data",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "429": {
            "description": "API rate limit exceeded"
          }
        },
        "security": [
          {
            "apiKeyAuth": []
          },
          {
            "bearerAuth": []
          }
        ]
      },
      "post": {
        "tags": [
          "Customer"
        ],
        "summary": "Create a new customer",
        "requestBody": {
          "description": "The customer object with the information that needs to be created",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Customer"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Customer created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Customer"
                }
              }
            }
          },
          "400": {
            "description": "Data invalid",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "401": {
            "description": "No Authorization header found or invalid token"
          },
          "403": {
            "description": "The current user is not allowed to access this company data",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "429": {
            "description": "API rate limit exceeded"
          }
        },
        "security": [
          {
            "apiKeyAuth": []
          },
          {
            "bearerAuth": []
          }
        ]
      }
    },
    "/core/latest/customers/{customer-id}": {
      "get": {
        "tags": [
          "Customer"
        ],
        "summary": "Returns a customer of a company based on given id",
        "parameters": [
          {
            "name": "customer-id",
            "in": "path",
            "description": "Id of the customer",
            "required": true,
            "schema": {
              "type": "string",
              "example": "1"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Found Customer",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Customer"
                }
              }
            }
          },
          "401": {
            "description": "No Authorization header found or invalid token"
          },
          "403": {
            "description": "The current user is not allowed to access this company data",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found"
          },
          "429": {
            "description": "API rate limit exceeded"
          }
        },
        "security": [
          {
            "apiKeyAuth": []
          },
          {
            "bearerAuth": []
          }
        ]
      },
      "put": {
        "tags": [
          "Customer"
        ],
        "summary": "Update an existing customer",
        "parameters": [
          {
            "name": "customer-id",
            "in": "path",
            "description": "Id of the customer to be updated",
            "required": true,
            "schema": {
              "type": "string",
              "example": "1"
            }
          }
        ],
        "requestBody": {
          "description": "The customer object with the information that needs to be updated",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Customer"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Customer updated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Customer"
                }
              }
            }
          },
          "400": {
            "description": "Data invalid",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "401": {
            "description": "No Authorization header found or invalid token"
          },
          "403": {
            "description": "The current user is not allowed to access this company data",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found"
          },
          "429": {
            "description": "API rate limit exceeded"
          }
        },
        "security": [
          {
            "apiKeyAuth": []
          },
          {
            "bearerAuth": []
          }
        ]
      },
      "delete": {
        "tags": [
          "Customer"
        ],
        "summary": "Delete a customer",
        "parameters": [
          {
            "name": "customer-id",
            "in": "path",
            "description": "Id of the customer to be deleted",
            "required": true,
            "schema": {
              "type": "string",
              "example": "1"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Customer deleted"
          },
          "400": {
            "description": "Could not delete Customer that contain orders",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "No Authorization header found or invalid token"
          },
          "403": {
            "description": "The current user is not allowed to access this company data",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found"
          },
          "429": {
            "description": "API rate limit exceeded"
          }
        },
        "security": [
          {
            "apiKeyAuth": []
          },
          {
            "bearerAuth": []
          }
        ]
      }
    },
    "/core/latest/customers/{customer-id}/additional-addresses": {
      "get": {
        "tags": [
          "Customer"
        ],
        "summary": "Gets all additional addresses of a customer",
        "parameters": [
          {
            "name": "customer-id",
            "in": "path",
            "description": "Id of the customer to get additional addresses",
            "required": true,
            "schema": {
              "type": "string",
              "example": "1"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "List of all additional addresses",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Address"
                  }
                }
              }
            }
          },
          "401": {
            "description": "No Authorization header found or invalid token"
          },
          "403": {
            "description": "The current user is not allowed to access this company data",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "429": {
            "description": "API rate limit exceeded"
          }
        },
        "security": [
          {
            "apiKeyAuth": []
          },
          {
            "bearerAuth": []
          }
        ]
      },
      "post": {
        "tags": [
          "Customer"
        ],
        "summary": "Creates a new customer's additional address",
        "parameters": [
          {
            "name": "customer-id",
            "in": "path",
            "description": "Id of the customer to add additional addresses to",
            "required": true,
            "schema": {
              "type": "string",
              "example": "1"
            }
          }
        ],
        "requestBody": {
          "description": "The additional address object with the information that needs to be created",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Address"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Customer's new additional address created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Address"
                }
              }
            }
          },
          "400": {
            "description": "Data invalid",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "401": {
            "description": "No Authorization header found or invalid token"
          },
          "403": {
            "description": "The current user is not allowed to access this company data",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "429": {
            "description": "API rate limit exceeded"
          }
        },
        "security": [
          {
            "apiKeyAuth": []
          },
          {
            "bearerAuth": []
          }
        ]
      }
    },
    "/core/latest/customers/{customer-id}/additional-addresses/{address-id}": {
      "put": {
        "tags": [
          "Customer"
        ],
        "summary": "Updates a Address",
        "operationId": "update additional-addresses",
        "parameters": [
          {
            "name": "address-id",
            "in": "path",
            "description": "The id of the requested Address",
            "required": true,
            "schema": {
              "type": "string",
              "example": "1"
            }
          },
          {
            "name": "customer-id",
            "in": "path",
            "description": "Id of the customer needed to update an additional address",
            "required": true,
            "schema": {
              "type": "string",
              "example": "1"
            }
          }
        ],
        "requestBody": {
          "description": "The Address object with the information that needs to be updated",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Address"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Updated additional-addresses",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Address"
                }
              }
            }
          },
          "400": {
            "description": "Data invalid",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "401": {
            "description": "No Authorization header found or invalid token"
          },
          "403": {
            "description": "The current user is not allowed to access this company data",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found"
          },
          "429": {
            "description": "API rate limit exceeded"
          }
        },
        "security": [
          {
            "apiKeyAuth": []
          },
          {
            "bearerAuth": []
          }
        ]
      },
      "delete": {
        "tags": [
          "Customer"
        ],
        "summary": "Delete an additional-address data by customer's id and customer's contact-id",
        "operationId": "delete additional-address",
        "parameters": [
          {
            "name": "address-id",
            "in": "path",
            "description": "Id of the additional address needed to be updated",
            "required": true,
            "schema": {
              "type": "string",
              "example": "1"
            }
          },
          {
            "name": "customer-id",
            "in": "path",
            "description": "Id of the customer to update an additional address deleted",
            "required": true,
            "schema": {
              "type": "string",
              "example": "1"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Additional-address deleted"
          },
          "401": {
            "description": "No Authorization header found or invalid token"
          },
          "403": {
            "description": "The current user is not allowed to access this company data",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found"
          },
          "429": {
            "description": "API rate limit exceeded"
          }
        },
        "security": [
          {
            "apiKeyAuth": []
          },
          {
            "bearerAuth": []
          }
        ]
      }
    },
    "/core/latest/customers/{customer-id}/contacts": {
      "get": {
        "tags": [
          "Customer"
        ],
        "summary": "Gets all contacts of a customer",
        "parameters": [
          {
            "name": "customer-id",
            "in": "path",
            "description": "Id of the customer to get all contacts from",
            "required": true,
            "schema": {
              "type": "string",
              "example": "1"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "List of contacts",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/CustomerContact"
                  }
                }
              }
            }
          },
          "401": {
            "description": "No Authorization header found or invalid token"
          },
          "403": {
            "description": "The current user is not allowed to access this company data",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "429": {
            "description": "API rate limit exceeded"
          }
        },
        "security": [
          {
            "apiKeyAuth": []
          },
          {
            "bearerAuth": []
          }
        ]
      },
      "post": {
        "tags": [
          "Customer"
        ],
        "summary": "Creates a new customer's contact",
        "parameters": [
          {
            "name": "customer-id",
            "in": "path",
            "description": "The id of the requested customer to add new contact to",
            "required": true,
            "schema": {
              "type": "string",
              "example": "1"
            }
          }
        ],
        "requestBody": {
          "description": "The CustomerContact object with the information that needs to be created",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CustomerContact"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Customer's new contact created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CustomerContact"
                }
              }
            }
          },
          "400": {
            "description": "Data invalid",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "401": {
            "description": "No Authorization header found or invalid token"
          },
          "403": {
            "description": "The current user is not allowed to access this company data",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "429": {
            "description": "API rate limit exceeded"
          }
        },
        "security": [
          {
            "apiKeyAuth": []
          },
          {
            "bearerAuth": []
          }
        ]
      }
    },
    "/core/latest/customers/{customer-id}/contacts/{contact-id}": {
      "put": {
        "tags": [
          "Customer"
        ],
        "summary": "Updates a CustomerContact",
        "operationId": "update CustomerContact",
        "parameters": [
          {
            "name": "contact-id",
            "in": "path",
            "description": "The id of the requested customer's contact to be updated",
            "required": true,
            "schema": {
              "type": "string",
              "example": "1"
            }
          },
          {
            "name": "customer-id",
            "in": "path",
            "description": "Id of the customer to have a contact updated",
            "required": true,
            "schema": {
              "type": "string",
              "example": "1"
            }
          }
        ],
        "requestBody": {
          "description": "The customer's contact object with the information that needs to be updated",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CustomerContact"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Updated contact",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CustomerContact"
                }
              }
            }
          },
          "400": {
            "description": "Data invalid",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "401": {
            "description": "No Authorization header found or invalid token"
          },
          "403": {
            "description": "The current user is not allowed to access this company data",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found"
          },
          "429": {
            "description": "API rate limit exceeded"
          }
        },
        "security": [
          {
            "apiKeyAuth": []
          },
          {
            "bearerAuth": []
          }
        ]
      },
      "delete": {
        "tags": [
          "Customer"
        ],
        "summary": "Delete a CustomerContact data by customer's id and customer's contact-id",
        "operationId": "delete CustomerContact",
        "parameters": [
          {
            "name": "contact-id",
            "in": "path",
            "description": "Id of a customer's contact to be deleted",
            "required": true,
            "schema": {
              "type": "string",
              "example": "1"
            }
          },
          {
            "name": "customer-id",
            "in": "path",
            "description": "Id of the requested customer to have a contact deleted",
            "required": true,
            "schema": {
              "type": "string",
              "example": "1"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Customer's contact deleted"
          },
          "401": {
            "description": "No Authorization header found or invalid token"
          },
          "403": {
            "description": "The current user is not allowed to access this company data",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found"
          },
          "429": {
            "description": "API rate limit exceeded"
          }
        },
        "security": [
          {
            "apiKeyAuth": []
          },
          {
            "bearerAuth": []
          }
        ]
      }
    },
    "/core/latest/generic-token": {
      "post": {
        "tags": [
          "Klara authentication generic"
        ],
        "summary": "Generate tokens to use Klara specific endpoint",
        "description": "Use this endpoint to get the access token for a specific user, and refresh token. <br />A grant_type of password is used for a Password grant, which requires username, password, access token, refresh token from scratch.<br />A grant_type of refresh_token is used for a Refresh token grant, which is used for acquiring the access token using refresh token.",
        "requestBody": {
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "type": "object",
                "properties": {
                  "username": {
                    "default": "",
                    "type": "string"
                  },
                  "password": {
                    "default": "",
                    "type": "string"
                  },
                  "grant_type": {
                    "default": "",
                    "type": "string"
                  },
                  "refresh_token": {
                    "default": "",
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Token created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicAPIToken"
                }
              }
            }
          },
          "400": {
            "description": "Could not get token"
          },
          "401": {
            "description": "Invalid credentials"
          },
          "429": {
            "description": "API rate limit exceeded"
          },
          "500": {
            "description": "Internal server error"
          }
        }
      }
    },
    "/core/latest/payroll-interface-file": {
      "post": {
        "tags": [
          "Accounting Interface"
        ],
        "summary": "Return payroll interface file",
        "description": "Return the payroll accounting interface file for a given salary run or payslips in CSV or JSON format",
        "parameters": [
          {
            "name": "file-format",
            "in": "query",
            "description": "File format",
            "schema": {
              "allOf": [
                {
                  "$ref": "#/components/schemas/FileType"
                },
                {
                  "default": "JSON"
                }
              ]
            }
          },
          {
            "name": "payslip-ids",
            "in": "query",
            "description": "List of payslip ids, separate by comma",
            "schema": {
              "type": "string",
              "example": "1,2,3,4"
            }
          },
          {
            "name": "salary-run-id",
            "in": "query",
            "description": "Salary run id",
            "schema": {
              "type": "integer",
              "example": 1
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Return the payroll accounting interface file for a given salary run or payslips in CSV or JSON format",
            "content": {
              "application/octet-stream": {}
            }
          },
          "400": {
            "description": "Data invalid",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "401": {
            "description": "No Authorization header found or invalid token"
          },
          "403": {
            "description": "The current user is not allowed to access this company data",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "429": {
            "description": "API rate limit exceeded"
          },
          "500": {
            "description": "Something went wrong on our side while processing the request. Please kindly contact our support."
          }
        },
        "security": [
          {
            "apiKeyAuth": []
          },
          {
            "bearerAuth": []
          }
        ]
      }
    },
    "/core/latest/subscriptions": {
      "post": {
        "tags": [
          "Subscription"
        ],
        "summary": "Create subscriptions for KLARA tenants.",
        "description": "A KLARA user might have multiple subscriptions. Each subscription will enable a set of feature inside KLARA platform. This endpoint allows to create subscriptions for a KLARA tenant. <p>Each subscription is subjective to its own terms and conditions. Please ask your KLARA contacts or see more details using the KLARA webclient.</p>",
        "parameters": [
          {
            "name": "marketing-code",
            "in": "query",
            "description": "Marketing code to identify which product will be subscribed. The marketing codes to create subscriptions for.",
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "example": "K-01-0002-00-M"
          }
        ],
        "responses": {
          "201": {
            "description": "Subscription created successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Subscription"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid subscription data",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Invalid credentials",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "The user has been disabled",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "API rate limit exceeded"
          },
          "500": {
            "description": "Something went wrong when creating subscriptions for the company",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "apiKeyAuth": []
          },
          {
            "bearerAuth": []
          }
        ]
      }
    },
    "/core/latest/tenants": {
      "post": {
        "tags": [
          "Authentication"
        ],
        "summary": "Returns all tenants of a user",
        "description": "A Klara user might have multiple tenants. Use this endpoint to get the list of tenants containing tenant id, company id.<br /> The tenant and company id returned by this endpoint can be used to generate tokens to access other endpoints. Use your KLARA username and password <strong> OR </strong> access-token to get the list of tenants. <br />",
        "requestBody": {
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "type": "object",
                "properties": {
                  "username": {
                    "type": "string"
                  },
                  "password": {
                    "type": "string"
                  },
                  "access_token": {
                    "type": "string"
                  }
                }
              },
              "encoding": {
                "access_token": {
                  "style": "form"
                },
                "password": {
                  "style": "form"
                },
                "username": {
                  "style": "form"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Found tenants",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Tenant"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Missing parameters",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Invalid credentials",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "The user has been disabled",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "API rate limit exceeded"
          },
          "500": {
            "description": "Something went wrong when getting list of tenants",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/core/latest/token": {
      "post": {
        "tags": [
          "Authentication"
        ],
        "summary": "Generate tokens to access other KLARA core endpoints",
        "description": "After obtaining tenant id and company id for the desired tenant, use this endpoint to get the access token for a specific tenant, and refresh token. <br />A grant_type of <strong>password</strong> is used for a Password grant, which requires username, password, tenant and company id to produce access token, refresh token from scratch.<br />A grant_type of <strong>refresh_token</strong> is used for a Refresh token grant, which is used for acquiring the access token using refresh token.<br />A grant_type of <strong>token_exchange</strong> performs an OAuth 2.0 Token Exchange (RFC 8693). Provide <strong>subject_token</strong> (the raw upstream Bearer token, without the 'Bearer ' prefix) and <strong>audience</strong> to identify the target token type.<br />Supported audience values:<ul><li><strong>cossa</strong> &mdash; exchanges a COSSA bearer token for a ePost access token.</li></ul><strong>Note:</strong> subject_token must be the raw token value without the 'Bearer ' prefix.",
        "requestBody": {
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "type": "object",
                "properties": {
                  "username": {
                    "default": "",
                    "type": "string"
                  },
                  "password": {
                    "default": "",
                    "type": "string"
                  },
                  "grant_type": {
                    "default": "",
                    "type": "string"
                  },
                  "tenant_id": {
                    "default": "",
                    "type": "string"
                  },
                  "company_id": {
                    "default": "",
                    "type": "string"
                  },
                  "refresh_token": {
                    "default": "",
                    "type": "string"
                  },
                  "subject_token": {
                    "default": "",
                    "type": "string"
                  },
                  "audience": {
                    "default": "",
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Token created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicAPIToken"
                }
              }
            }
          },
          "400": {
            "description": "Could not get token"
          },
          "401": {
            "description": "Invalid credentials"
          },
          "429": {
            "description": "API rate limit exceeded"
          },
          "500": {
            "description": "Internal server error"
          }
        }
      }
    },
    "/core/latest/token/by-microsoft": {
      "post": {
        "tags": [
          "Authentication"
        ],
        "summary": "Exchange Microsoft access token for system token",
        "description": "Provide a Microsoft access token and tenant id to exchange for a system token.",
        "requestBody": {
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "type": "object",
                "properties": {
                  "microsoft_access_token": {
                    "type": "string"
                  },
                  "tenant_id": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Token created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AccessTokenResponse"
                }
              }
            }
          },
          "400": {
            "description": "Could not get token"
          },
          "401": {
            "description": "Invalid credentials"
          },
          "429": {
            "description": "API rate limit exceeded"
          },
          "500": {
            "description": "Internal server error"
          }
        }
      }
    },
    "/core/latest/vat-cases": {
      "get": {
        "tags": [
          "Company general"
        ],
        "summary": "Returns VAT case list.",
        "parameters": [
          {
            "name": "applicability",
            "in": "query",
            "schema": {
              "$ref": "#/components/schemas/ApplicabilityVatCaseType"
            }
          },
          {
            "name": "Accept-Language",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "VAT cases",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/VatCase"
                  }
                }
              }
            }
          },
          "401": {
            "description": "No Authorization header found or invalid token"
          },
          "403": {
            "description": "The current user is not allowed to access this company data",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          }
        },
        "security": [
          {
            "apiKeyAuth": []
          },
          {
            "bearerAuth": []
          }
        ]
      }
    },
    "/core/latest/vat-cases/{vat-case-id}": {
      "get": {
        "tags": [
          "Company general"
        ],
        "summary": "Get the VAT case by Id.",
        "parameters": [
          {
            "name": "vat-case-id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Accept-Language",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "VAT case",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VatCase"
                }
              }
            }
          },
          "401": {
            "description": "No Authorization header found or invalid token"
          },
          "403": {
            "description": "The current user is not allowed to access this company data",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          }
        },
        "security": [
          {
            "apiKeyAuth": []
          },
          {
            "bearerAuth": []
          }
        ]
      }
    },
    "/core/v1/accounting/accounts": {
      "get": {
        "tags": [
          "Accounting"
        ],
        "summary": "List Klara master chart-of-account rows.",
        "description": "Returns the canonical debit/credit accounts maintained by Klara as the seed of any company's bookkeeping. The data is global — the same chart of accounts is returned for every tenant, so there are no tenant or company path parameters. When the optional <code>legal-form</code> query parameter is supplied, only accounts that carry a translation for that legal form are returned, and the <code>name</code> field is resolved from the legal-form-specific translation column. The <code>Accept-Language</code> header selects which translation is used; if absent or unsupported the platform default applies. The endpoint is a pure read — idempotent, no side effects. Any authenticated bearer token is accepted; the downstream service declares no role or permission requirement on this endpoint.",
        "parameters": [
          {
            "name": "legal-form",
            "in": "query",
            "description": "Restricts the result to accounts that carry a translation for the given Swiss legal form, and resolves <code>name</code> from that legal-form-specific column. Allowed values: <code>LIMITED_LIABILITY</code>, <code>CORPORATION</code>, <code>OR</code>, <code>INDIVIDUALLY_OWNED_COMPANY</code>, <code>ASSOCIATION</code>, <code>SIMPLE_PARTNERSHIP</code>, <code>GENERAL_PARTNERSHIP</code>, <code>LIMITED_PARTNERSHIP</code>, <code>COOPERATIVE_COMPANY</code>, <code>FOUNDATION</code>.",
            "schema": {
              "enum": [
                "LIMITED_LIABILITY",
                "CORPORATION",
                "OR",
                "INDIVIDUALLY_OWNED_COMPANY",
                "ASSOCIATION",
                "SIMPLE_PARTNERSHIP",
                "GENERAL_PARTNERSHIP",
                "LIMITED_PARTNERSHIP",
                "COOPERATIVE_COMPANY",
                "FOUNDATION"
              ],
              "type": "string",
              "example": "CORPORATION"
            },
            "example": "CORPORATION"
          },
          {
            "name": "Accept-Language",
            "in": "header",
            "description": "IETF language tag used to resolve the localized <code>name</code> field of each account. Examples: <code>de-CH</code>, <code>fr-CH</code>, <code>it-CH</code>, <code>en</code>.",
            "schema": {
              "type": "string",
              "example": "de-CH"
            },
            "example": "de-CH"
          }
        ],
        "responses": {
          "200": {
            "description": "Master accounts, sorted by <code>code</code> ascending. Empty array when the chart of accounts has not been seeded yet.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/PublicApiAccount"
                  }
                }
              }
            }
          },
          "401": {
            "description": "No Authorization header found or invalid token"
          },
          "404": {
            "description": "The supplied <code>legal-form</code> value does not match any known legal form.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "429": {
            "description": "API rate limit exceeded"
          },
          "500": {
            "description": "Something went wrong on our side while processing the request. Please kindly contact our support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          }
        },
        "security": [
          {
            "apiKeyAuth": []
          },
          {
            "bearerAuth": []
          }
        ]
      }
    },
    "/core/v1/accounting/accounts/account-displaying": {
      "get": {
        "tags": [
          "Accounting"
        ],
        "summary": "List the account-displaying picker rows for the authenticated company.",
        "description": "Returns a flat list of <code>AccountDisplaying</code> rows for every account in the caller's company chart of accounts. Each row represents one selectable combination that a bookkeeper can pick when entering a manual journal line. Tenant and company are derived from the bearer token — there are no tenant or company path parameters.<p><strong>How rows are produced:</strong> For each master account the downstream service checks whether the account carries any linked sub-account definitions (e.g. a bank account linked to specific bank-accounts, a VAT account linked to VAT-rate items). If the account has <em>no</em> sub-account definitions, exactly one bare row is emitted with <code>combinedCode</code> equal to the bare account code (e.g. <code>\"3000\"</code>), <code>linkType</code> equal to <code>null</code>, and <code>specificationItem</code> equal to <code>null</code>. If the account has one or more sub-account link specifications, one row is emitted per individual sub-account entry, numbered sequentially across <em>all</em> link types with a 0-based counter suffix: <code>\"1020-0\"</code>, <code>\"1020-1\"</code>, …</p><p><strong>combinedCode:</strong> <code>\"&lt;accountCode&gt;-&lt;i&gt;\"</code> when a sub-account exists (e.g. <code>\"1020-0\"</code>), or the bare account code string (e.g. <code>\"3000\"</code>) when <code>linkType</code> is <code>null</code>. The suffix index is a flat 0-based counter per account, spanning all link types in declaration order.</p><p><strong>combinedName:</strong> <code>\"&lt;accountName&gt; (&lt;subAccountDisplay&gt;)\"</code> when a sub-account exists (e.g. <code>\"Bank (UBS)\"</code>), or the bare account name (e.g. <code>\"Bürobedarf\"</code>) when <code>linkType</code> is <code>null</code>.</p><p><strong>parentAccount:</strong> the full master account this row belongs to. Always populated, including for bare rows.</p><p><strong>linkType:</strong> the link-type category name (e.g. <code>\"BANK\"</code>, <code>\"CUSTOMER\"</code>, <code>\"VAT_RATE\"</code>). <code>null</code> when the account has no sub-account definitions.</p><p><strong>linkDisplay:</strong> the human-readable label for the link type in the current locale (e.g. <code>\"Bank account\"</code>). Falls back to the German label when no translation exists for the requested language. <code>null</code> when <code>linkType</code> is <code>null</code>.</p><p><strong>linkOptional:</strong> <code>true</code> when the sub-account selection is optional for the user (link keys are separated by <code>;</code> in the account definition); <code>false</code> when selecting a sub-account is mandatory (link keys separated by <code>,</code>); <code>null</code> when the account has no sub-account definitions.</p><p><strong>specificationItem:</strong> the resolved sub-account entry for this row. Its <code>link</code> field is the URI that must be round-tripped back to the booking endpoint when the user selects this row. Its <code>display</code> field is the human-readable label shown to the bookkeeper (e.g. <code>\"UBS\"</code>, <code>\"8.1 %\"</code>). <code>null</code> when <code>linkType</code> is <code>null</code>.</p><p>Row order is stable: accounts are sorted by code ascending (same order as <code>GET /core/v1/accounting/accounts</code>); sub-account rows within each account preserve the link-type declaration order and then the entry order returned by the underlying service.</p>The endpoint is a pure read — idempotent, no side effects. The caller must hold the <code>ACCOUNTING</code> permission on the company in scope.",
        "parameters": [
          {
            "name": "legal-form",
            "in": "query",
            "description": "When supplied, restricts the result to accounts that carry a translation for the given Swiss legal form and resolves the <code>parentAccount.name</code> field from the legal-form-specific translation column. When omitted, all accounts are returned and <code>account.name</code> is resolved from the generic language column. Allowed values: <code>LIMITED_LIABILITY</code>, <code>CORPORATION</code>, <code>OR</code>, <code>INDIVIDUALLY_OWNED_COMPANY</code>, <code>ASSOCIATION</code>, <code>SIMPLE_PARTNERSHIP</code>, <code>GENERAL_PARTNERSHIP</code>, <code>LIMITED_PARTNERSHIP</code>, <code>COOPERATIVE_COMPANY</code>, <code>FOUNDATION</code>.",
            "schema": {
              "enum": [
                "LIMITED_LIABILITY",
                "CORPORATION",
                "OR",
                "INDIVIDUALLY_OWNED_COMPANY",
                "ASSOCIATION",
                "SIMPLE_PARTNERSHIP",
                "GENERAL_PARTNERSHIP",
                "LIMITED_PARTNERSHIP",
                "COOPERATIVE_COMPANY",
                "FOUNDATION"
              ],
              "type": "string",
              "example": "CORPORATION"
            },
            "example": "CORPORATION"
          },
          {
            "name": "Accept-Language",
            "in": "header",
            "description": "IETF language tag used to localize the <code>parentAccount.name</code> field of each row and the <code>linkDisplay</code> label. Falls back to German when no translation exists for the requested language. Examples: <code>de-CH</code>, <code>fr-CH</code>, <code>it-CH</code>, <code>en</code>.",
            "schema": {
              "type": "string",
              "example": "de-CH"
            },
            "example": "de-CH"
          }
        ],
        "responses": {
          "200": {
            "description": "Flat list of account-displaying rows, sorted by account code ascending. Each row contains <code>combinedCode</code>, <code>combinedName</code>, <code>parentAccount</code>, and the link fields populated for sub-account rows or <code>null</code> for bare rows. Returns an empty array when no accounts match the supplied <code>legal-form</code>.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/PublicApiAccountDisplaying"
                  }
                }
              }
            }
          },
          "401": {
            "description": "No Authorization header found or invalid token"
          },
          "403": {
            "description": "The current user is not allowed to access this company data",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "404": {
            "description": "The company associated with the caller's session could not be resolved by the downstream accounting service, or the supplied <code>legal-form</code> value does not match any known legal form.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "429": {
            "description": "API rate limit exceeded"
          },
          "500": {
            "description": "Something went wrong on our side while processing the request. Please kindly contact our support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          }
        },
        "security": [
          {
            "apiKeyAuth": []
          },
          {
            "bearerAuth": []
          }
        ]
      }
    },
    "/core/v1/accounting/accounts/by-code/{accountCode}": {
      "get": {
        "tags": [
          "Accounting"
        ],
        "summary": "Resolve a Klara master account by its chart-of-account code.",
        "description": "Loads a single master account row from Klara's global chart of accounts, identified by its numeric <code>accountCode</code>. The data is global — the same chart of accounts is shared across every tenant, so there are no tenant or company path parameters. When the optional <code>legal-form</code> query parameter is supplied, the <code>name</code> field is resolved from the legal-form-specific translation column instead of the generic one. The <code>Accept-Language</code> header selects which translation is used; if absent or unsupported the platform default applies. The endpoint is a pure read — idempotent, no side effects. Any authenticated bearer token is accepted; the downstream service declares no role or permission requirement on this endpoint.",
        "parameters": [
          {
            "name": "accountCode",
            "in": "path",
            "description": "Numeric chart-of-account code as printed on the Klara master chart of accounts (e.g. <code>1000</code> for cash, <code>6000</code> for material expense).",
            "required": true,
            "schema": {
              "type": "string",
              "example": "6000"
            },
            "example": 6000
          },
          {
            "name": "legal-form",
            "in": "query",
            "description": "When supplied, resolves <code>name</code> from the legal-form-specific translation column. Allowed values: <code>LIMITED_LIABILITY</code>, <code>CORPORATION</code>, <code>OR</code>, <code>INDIVIDUALLY_OWNED_COMPANY</code>, <code>ASSOCIATION</code>, <code>SIMPLE_PARTNERSHIP</code>, <code>GENERAL_PARTNERSHIP</code>, <code>LIMITED_PARTNERSHIP</code>, <code>COOPERATIVE_COMPANY</code>, <code>FOUNDATION</code>.",
            "schema": {
              "enum": [
                "LIMITED_LIABILITY",
                "CORPORATION",
                "OR",
                "INDIVIDUALLY_OWNED_COMPANY",
                "ASSOCIATION",
                "SIMPLE_PARTNERSHIP",
                "GENERAL_PARTNERSHIP",
                "LIMITED_PARTNERSHIP",
                "COOPERATIVE_COMPANY",
                "FOUNDATION"
              ],
              "type": "string",
              "example": "CORPORATION"
            },
            "example": "CORPORATION"
          },
          {
            "name": "Accept-Language",
            "in": "header",
            "description": "IETF language tag used to resolve the localized <code>name</code> field of the account. Examples: <code>de-CH</code>, <code>fr-CH</code>, <code>it-CH</code>, <code>en</code>.",
            "schema": {
              "type": "string",
              "example": "de-CH"
            },
            "example": "de-CH"
          }
        ],
        "responses": {
          "200": {
            "description": "The master account matching <code>accountCode</code>.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiAccount"
                }
              }
            }
          },
          "401": {
            "description": "No Authorization header found or invalid token"
          },
          "404": {
            "description": "No master account exists for the supplied <code>accountCode</code>, or the supplied <code>legal-form</code> value does not match any known legal form.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "429": {
            "description": "API rate limit exceeded"
          },
          "500": {
            "description": "Something went wrong on our side while processing the request. Please kindly contact our support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          }
        },
        "security": [
          {
            "apiKeyAuth": []
          },
          {
            "bearerAuth": []
          }
        ]
      }
    },
    "/core/v1/accounting/booking-types": {
      "get": {
        "tags": [
          "Accounting"
        ],
        "summary": "List Klara master accounting booking types.",
        "description": "Returns the canonical catalog of accounting booking types maintained by Klara — the stable set of bookkeeping operations (general-ledger postings, payable / receivable invoices, payments, credit notes, prepayments, amortizations, delimitations) that every Klara company can post against. The data is global — the same catalog is returned for every tenant, so there are no tenant or company path parameters. The <code>Accept-Language</code> header selects which translation of the human-readable <code>description</code> is returned; if absent or unsupported the German translation is used as a fallback. The endpoint is a pure read — idempotent, no side effects. Any authenticated bearer token is accepted; the downstream service declares no role or permission requirement on this endpoint.",
        "parameters": [
          {
            "name": "Accept-Language",
            "in": "header",
            "description": "IETF language tag used to resolve the localized <code>description</code> of each booking type. Examples: <code>de-CH</code>, <code>fr-CH</code>, <code>it-CH</code>, <code>en</code>. Falls back to the German translation when no translation exists for the requested language.",
            "schema": {
              "type": "string",
              "example": "de-CH"
            },
            "example": "de-CH"
          }
        ],
        "responses": {
          "200": {
            "description": "Master booking types, ordered by <code>code</code> ascending. Empty array when the catalog has not been seeded yet.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/PublicApiBookingType"
                  }
                }
              }
            }
          },
          "401": {
            "description": "No Authorization header found or invalid token"
          },
          "429": {
            "description": "API rate limit exceeded"
          },
          "500": {
            "description": "Something went wrong on our side while processing the request. Please kindly contact our support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          }
        },
        "security": [
          {
            "apiKeyAuth": []
          },
          {
            "bearerAuth": []
          }
        ]
      }
    },
    "/core/v1/accounting/business-case-templates": {
      "get": {
        "tags": [
          "Accounting"
        ],
        "summary": "List Klara master accounting business-case templates.",
        "description": "Returns the global catalog of business-case templates — the manual-journal categories that drive the booking form (operating expenses, salary payments, asset purchases, …). The catalog is global Klara reference data: the same list is returned for every tenant, so there are no tenant or company path parameters. The <code>Accept-Language</code> header selects which translation of the human-readable <code>display</code> label is returned; if absent or unsupported the German translation is used as a fallback and the full per-language <code>i18n</code> / <code>keywordI18ns</code> maps are returned for client-side rendering. Optional <code>orderColumns</code> / <code>offset</code> / <code>limit</code> query parameters are forwarded verbatim to the downstream catalog for ordering and pagination. The endpoint is a pure read — idempotent, no side effects. Requires a bearer token whose principal carries the <code>ACCOUNTING_GET_BUSINESS_CASE_TEMPLATE</code> permission.",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "description": "Maximum number of templates to return. When omitted, the downstream service returns the full catalog.",
            "required": false,
            "schema": {
              "type": "integer",
              "example": 50
            },
            "example": 50
          },
          {
            "name": "offset",
            "in": "query",
            "description": "Zero-based index of the first template to return. When omitted, the response starts at the first row.",
            "required": false,
            "schema": {
              "type": "integer",
              "example": 0
            },
            "example": 0
          },
          {
            "name": "orderColumns",
            "in": "query",
            "description": "Names of columns to order the result by, ascending. Repeat the query parameter for multi-column ordering (e.g. <code>?orderColumns=group&amp;orderColumns=code</code>).",
            "required": false,
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              },
              "example": "code"
            },
            "example": "code"
          },
          {
            "name": "Accept-Language",
            "in": "header",
            "description": "IETF language tag used to resolve the localized <code>display</code> label of each template. Examples: <code>de-CH</code>, <code>fr-CH</code>, <code>it-CH</code>, <code>en</code>. Falls back to the German translation when no translation exists for the requested language.",
            "schema": {
              "type": "string",
              "example": "de-CH"
            },
            "example": "de-CH"
          }
        ],
        "responses": {
          "200": {
            "description": "Business-case templates matching the supplied ordering and pagination.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/PublicApiBusinessCaseTemplate"
                  }
                }
              }
            }
          },
          "401": {
            "description": "No Authorization header found or invalid token"
          },
          "403": {
            "description": "The current user is not allowed to access this company data",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "429": {
            "description": "API rate limit exceeded"
          },
          "500": {
            "description": "Something went wrong on our side while processing the request. Please kindly contact our support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          }
        },
        "security": [
          {
            "apiKeyAuth": []
          },
          {
            "bearerAuth": []
          }
        ]
      }
    },
    "/core/v1/accounting/business-case-templates/{businessCaseTemplateId}": {
      "get": {
        "tags": [
          "Accounting"
        ],
        "summary": "Read a single Klara master accounting business-case template by id.",
        "description": "Returns one business-case template from the global Klara catalog — a manual-journal category usable when entering a booking (for example operating expenses, salary payments, asset purchases). The catalog is global Klara reference data, so this endpoint has no tenant or company path parameters; only the catalogue id selects the template. The <code>Accept-Language</code> header selects which translation of the human-readable <code>display</code> label is returned; if absent or unsupported the German translation is used as a fallback and the full per-language <code>i18n</code> / <code>keywordI18ns</code> maps are returned for client-side rendering. The endpoint is a pure read — idempotent, no side effects. Returns <code>404</code> when no template with the requested id exists in the catalog. Requires a bearer token whose principal carries the <code>ACCOUNTING_GET_BUSINESS_CASE_TEMPLATE</code> permission.",
        "parameters": [
          {
            "name": "businessCaseTemplateId",
            "in": "path",
            "description": "Numeric primary-key id of the business-case template in the Klara master catalog. Obtain it from a prior call to <code>GET /core/v1/accounting/business-case-templates</code>.",
            "required": true,
            "schema": {
              "format": "int64",
              "type": "integer",
              "example": 101
            },
            "example": 101
          },
          {
            "name": "Accept-Language",
            "in": "header",
            "description": "IETF language tag used to resolve the localized <code>display</code> label of the template. Examples: <code>de-CH</code>, <code>fr-CH</code>, <code>it-CH</code>, <code>en</code>. Falls back to the German translation when no translation exists for the requested language.",
            "schema": {
              "type": "string",
              "example": "de-CH"
            },
            "example": "de-CH"
          }
        ],
        "responses": {
          "200": {
            "description": "Business-case template matching the supplied id.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiBusinessCaseTemplate"
                }
              }
            }
          },
          "401": {
            "description": "No Authorization header found or invalid token"
          },
          "403": {
            "description": "The current user is not allowed to access this company data",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "404": {
            "description": "No business-case template carries the requested id."
          },
          "429": {
            "description": "API rate limit exceeded"
          },
          "500": {
            "description": "Something went wrong on our side while processing the request. Please kindly contact our support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          }
        },
        "security": [
          {
            "apiKeyAuth": []
          },
          {
            "bearerAuth": []
          }
        ]
      }
    },
    "/core/v1/accounting/business-cases": {
      "get": {
        "tags": [
          "Accounting"
        ],
        "summary": "Hydrate a business case from a template id for the authenticated company.",
        "description": "Loads the fully hydrated business-case aggregate the booking form needs: the template id, the company-VAT and fiscal-year context resolved from the optional date filters, the pre-translated display label, and the recursive snippet / field tree. When <code>dateForFilteringFiscalYear</code> is supplied it drives the fiscal-year resolution; otherwise <code>dateForFilteringCompanyVat</code> is used; otherwise the downstream service resolves the fiscal year that covers today. Tenant and company are derived from the bearer-token session — they are never accepted from the URL. The endpoint is a pure read — idempotent, no side effects. The caller must hold the <code>ACCOUNTING</code> permission on the company in scope.",
        "parameters": [
          {
            "name": "businessCaseTemplateId",
            "in": "query",
            "description": "Numeric id of the business-case template to hydrate. Obtain it from <code>GET /core/v1/accounting/companies/current/business-case-templates</code>.",
            "required": true,
            "schema": {
              "format": "int64",
              "type": "integer",
              "example": 101
            },
            "example": 101
          },
          {
            "name": "dateForFilteringCompanyVat",
            "in": "query",
            "description": "ISO date (<code>yyyy-MM-dd</code>) used to resolve the company-VAT regime applicable to the business case. Used as the fallback for <code>dateForFilteringFiscalYear</code> when that is omitted.",
            "required": false,
            "schema": {
              "format": "date",
              "type": "string",
              "example": "2024-06-15"
            },
            "example": "2024-06-15"
          },
          {
            "name": "dateForFilteringFiscalYear",
            "in": "query",
            "description": "ISO date (<code>yyyy-MM-dd</code>) used to resolve the fiscal year that hydrates the business case. When omitted, falls back to <code>dateForFilteringCompanyVat</code>; when both are omitted the downstream service resolves the fiscal year that covers today.",
            "required": false,
            "schema": {
              "format": "date",
              "type": "string",
              "example": "2024-06-15"
            },
            "example": "2024-06-15"
          },
          {
            "name": "Accept-Language",
            "in": "header",
            "description": "IETF language tag used to translate the snippet labels and field captions. Examples: <code>de-CH</code>, <code>fr-CH</code>, <code>it-CH</code>, <code>en</code>.",
            "schema": {
              "type": "string",
              "example": "de-CH"
            },
            "example": "de-CH"
          }
        ],
        "responses": {
          "200": {
            "description": "Hydrated business-case aggregate for the requested template.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiBusinessCase"
                }
              }
            }
          },
          "400": {
            "description": "One of <code>dateForFilteringFiscalYear</code> / <code>dateForFilteringCompanyVat</code> is not a valid ISO date (<code>yyyy-MM-dd</code>), or the supplied <code>businessCaseTemplateId</code> is not valid for the company's legal form or VAT regime.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "401": {
            "description": "No Authorization header found or invalid token"
          },
          "403": {
            "description": "The current user is not allowed to access this company data",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "404": {
            "description": "No business-case template matches the supplied <code>businessCaseTemplateId</code> in the caller's company scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "429": {
            "description": "API rate limit exceeded"
          },
          "500": {
            "description": "Something went wrong on our side while processing the request. Please kindly contact our support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          }
        },
        "security": [
          {
            "apiKeyAuth": []
          },
          {
            "bearerAuth": []
          }
        ]
      }
    },
    "/core/v1/accounting/business-cases/{businessCaseId}": {
      "get": {
        "tags": [
          "Accounting"
        ],
        "summary": "Read a persisted business-case instance by its id for the authenticated company.",
        "description": "Loads the fully hydrated business-case aggregate that was previously persisted for the authenticated company: the template id, the company-VAT and fiscal-year context that were in force when the case was booked, the pre-translated display label, the recursive snippet / field tree with the persisted scripted values overlaid, and the comma-separated list of booking numbers already generated for it. Tenant and company are derived from the bearer-token session — they are never accepted from the URL; the supplied <code>businessCaseId</code> is matched against the caller's company so that an id owned by another company surfaces as <code>404</code>. The endpoint is a pure read — idempotent, no side effects. The caller must hold the <code>ACCOUNTING</code> permission on the company in scope.",
        "parameters": [
          {
            "name": "businessCaseId",
            "in": "path",
            "description": "Numeric primary-key id of the persisted business-case instance to hydrate. Obtain it from a prior booking response (for example <code>POST /core/v1/accounting/bookings</code>) or from a journal listing.",
            "required": true,
            "schema": {
              "format": "int64",
              "type": "integer",
              "example": 5001
            },
            "example": 5001
          },
          {
            "name": "Accept-Language",
            "in": "header",
            "description": "IETF language tag used to translate the snippet labels and field captions. Examples: <code>de-CH</code>, <code>fr-CH</code>, <code>it-CH</code>, <code>en</code>.",
            "schema": {
              "type": "string",
              "example": "de-CH"
            },
            "example": "de-CH"
          }
        ],
        "responses": {
          "200": {
            "description": "Hydrated business-case aggregate for the requested id.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiBusinessCase"
                }
              }
            }
          },
          "400": {
            "description": "The supplied <code>businessCaseId</code> is not a valid numeric id.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "401": {
            "description": "No Authorization header found or invalid token"
          },
          "403": {
            "description": "The current user is not allowed to access this company data",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "404": {
            "description": "No business case matches the supplied <code>businessCaseId</code> in the caller's company scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "429": {
            "description": "API rate limit exceeded"
          },
          "500": {
            "description": "Something went wrong on our side while processing the request. Please kindly contact our support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          }
        },
        "security": [
          {
            "apiKeyAuth": []
          },
          {
            "bearerAuth": []
          }
        ]
      }
    },
    "/core/v1/accounting/business-cases/v2": {
      "get": {
        "tags": [
          "Accounting"
        ],
        "summary": "Hydrate a business case from a template id, scoped to a single snippet.",
        "description": "Snippet-scoped variant of <code>GET /core/v1/accounting/business-cases</code>: hydrates only the template root plus the snippet identified by <code>snippet-id</code>, so the booking UI can stream the form one snippet at a time instead of loading the whole tree up-front. When <code>dateForFilteringFiscalYear</code> is supplied it drives the fiscal-year resolution; otherwise <code>dateForFilteringCompanyVat</code> is used; otherwise the downstream service resolves the fiscal year that covers today. When <code>group-insurance-by-insurer</code> is <code>true</code> (the default), social-insurance entries that share the same display + value pair are collapsed, keeping the entry with the smallest numeric id. Tenant and company are derived from the bearer-token session — they are never accepted from the URL. The endpoint is a pure read — idempotent, no side effects. The caller must hold the <code>ACCOUNTING</code> permission on the company in scope.",
        "parameters": [
          {
            "name": "businessCaseTemplateId",
            "in": "query",
            "description": "Numeric id of the business-case template to hydrate. Obtain it from <code>GET /core/v1/accounting/companies/current/business-case-templates</code>.",
            "required": true,
            "schema": {
              "format": "int64",
              "type": "integer",
              "example": 101
            },
            "example": 101
          },
          {
            "name": "dateForFilteringCompanyVat",
            "in": "query",
            "description": "ISO date (<code>yyyy-MM-dd</code>) used to resolve the company-VAT regime applicable to the business case. Used as the fallback for <code>dateForFilteringFiscalYear</code> when that is omitted.",
            "required": false,
            "schema": {
              "format": "date",
              "type": "string",
              "example": "2024-06-15"
            },
            "example": "2024-06-15"
          },
          {
            "name": "dateForFilteringFiscalYear",
            "in": "query",
            "description": "ISO date (<code>yyyy-MM-dd</code>) used to resolve the fiscal year that hydrates the business case. When omitted, falls back to <code>dateForFilteringCompanyVat</code>; when both are omitted the downstream service resolves the fiscal year that covers today.",
            "required": false,
            "schema": {
              "format": "date",
              "type": "string",
              "example": "2024-06-15"
            },
            "example": "2024-06-15"
          },
          {
            "name": "group-insurance-by-insurer",
            "in": "query",
            "description": "When <code>true</code>, collapses social-insurance entries that share the same display + value pair, keeping the entry with the smallest numeric id. Defaults to <code>true</code>. Allowed values: <code>true</code>, <code>false</code>.",
            "required": false,
            "schema": {
              "default": "true",
              "type": "boolean",
              "example": true
            },
            "example": true
          },
          {
            "name": "snippet-id",
            "in": "query",
            "description": "Numeric id of the snippet currently activated by the user; v2 hydrates only this snippet plus the template root. When omitted, only the template root is hydrated.",
            "required": false,
            "schema": {
              "format": "int64",
              "type": "integer",
              "example": 42
            },
            "example": 42
          },
          {
            "name": "snippet-value",
            "in": "query",
            "description": "Currently ignored on the downstream side; reserved for a future optimisation that would load external entries only for the activated value (for example, payment dates of a single employee). Safe to omit.",
            "required": false,
            "schema": {
              "type": "string",
              "example": "EMP-1001"
            },
            "example": "EMP-1001"
          },
          {
            "name": "Accept-Language",
            "in": "header",
            "description": "IETF language tag used to translate the snippet labels and field captions. Examples: <code>de-CH</code>, <code>fr-CH</code>, <code>it-CH</code>, <code>en</code>.",
            "schema": {
              "type": "string",
              "example": "de-CH"
            },
            "example": "de-CH"
          }
        ],
        "responses": {
          "200": {
            "description": "Hydrated business-case aggregate for the requested template and snippet.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiBusinessCase"
                }
              }
            }
          },
          "400": {
            "description": "One of <code>dateForFilteringFiscalYear</code> / <code>dateForFilteringCompanyVat</code> is not a valid ISO date (<code>yyyy-MM-dd</code>), or the supplied <code>businessCaseTemplateId</code> is not valid for the company's legal form or VAT regime.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "401": {
            "description": "No Authorization header found or invalid token"
          },
          "403": {
            "description": "The current user is not allowed to access this company data",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "404": {
            "description": "No business-case template matches the supplied <code>businessCaseTemplateId</code> in the caller's company scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "429": {
            "description": "API rate limit exceeded"
          },
          "500": {
            "description": "Something went wrong on our side while processing the request. Please kindly contact our support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          }
        },
        "security": [
          {
            "apiKeyAuth": []
          },
          {
            "bearerAuth": []
          }
        ]
      }
    },
    "/core/v1/accounting/companies/current": {
      "get": {
        "tags": [
          "Accounting"
        ],
        "summary": "Get the accounting configuration of the authenticated company.",
        "description": "Returns the dunning waiting periods configured for the authenticated caller's company together with the canonical compensation-side company URI. Tenant and company are derived from the bearer token — there are no path or query parameters to override them. When the company has no accounting configuration row persisted yet, the downstream service synthesises a default record (<code>id</code> = <code>null</code>, <code>waitingDunningTime</code> = <code>5</code>, <code>dunningWaitingTimeLevelOne</code> / <code>Two</code> / <code>Three</code> = <code>10</code>) so the response shape stays the same. The endpoint is a pure read — idempotent, no side effects. The caller must hold the <code>ACCOUNTING</code> permission on the company in scope.",
        "responses": {
          "200": {
            "description": "Accounting configuration of the caller's company.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiAccountingCompany"
                }
              }
            }
          },
          "401": {
            "description": "No Authorization header found or invalid token"
          },
          "403": {
            "description": "The current user is not allowed to access this company data",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "404": {
            "description": "The company associated with the caller's session could not be resolved by the downstream accounting service.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "429": {
            "description": "API rate limit exceeded"
          },
          "500": {
            "description": "Something went wrong on our side while processing the request. Please kindly contact our support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          }
        },
        "security": [
          {
            "apiKeyAuth": []
          },
          {
            "bearerAuth": []
          }
        ]
      }
    },
    "/core/v1/accounting/companies/current/business-case-templates": {
      "get": {
        "tags": [
          "Accounting"
        ],
        "summary": "List business-case templates available to the authenticated company, grouped by financial-year period.",
        "description": "Returns the manual-journal categories (\"business-case templates\") the caller's company is allowed to book against, grouped by the financial-year period in which they are valid. Each period carries its <code>periodFrom</code> / <code>periodTo</code>, the company's <code>legalForm</code> and active VAT regime, and the templates that pass the legal-form / VAT-regime filters for that period. Templates are sorted by <code>code</code>; the <code>display</code> field is pre-translated using the <code>Accept-Language</code> header and the full per-language map is also returned in <code>i18n</code> / <code>keywordI18ns</code>. Tenant and company are derived from the bearer token — there are no path or query parameters to override them. The endpoint is a pure read — idempotent, no side effects. The caller must hold the <code>ACCOUNTING</code> permission on the company in scope.",
        "parameters": [
          {
            "name": "Accept-Language",
            "in": "header",
            "description": "IETF language tag used to translate the <code>display</code> field of each template. Examples: <code>de-CH</code>, <code>fr-CH</code>, <code>it-CH</code>, <code>en</code>.",
            "schema": {
              "type": "string",
              "example": "de-CH"
            },
            "example": "de-CH"
          }
        ],
        "responses": {
          "200": {
            "description": "Business-case templates grouped by financial-year period. May be an empty array when the company has no open fiscal year yet.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/PublicApiBusinessCasePeriod"
                  }
                }
              }
            }
          },
          "401": {
            "description": "No Authorization header found or invalid token"
          },
          "403": {
            "description": "The current user is not allowed to access this company data",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "404": {
            "description": "The company associated with the caller's session could not be resolved by the downstream accounting service.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "429": {
            "description": "API rate limit exceeded"
          },
          "500": {
            "description": "Something went wrong on our side while processing the request. Please kindly contact our support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          }
        },
        "security": [
          {
            "apiKeyAuth": []
          },
          {
            "bearerAuth": []
          }
        ]
      }
    },
    "/core/v1/accounting/companies/current/financial-years": {
      "get": {
        "tags": [
          "Accounting"
        ],
        "summary": "List active financial-year periods of the authenticated company.",
        "description": "Returns the company's currently active fiscal-year periods (status <code>OPEN</code> or <code>CLOSING</code>), one entry per legal-form / VAT-regime combination valid in the period. When every period shares the same <code>legalForm</code> and VAT regime the downstream service collapses them into a single aggregated period with <code>periodFrom</code> set to the earliest start date and <code>periodTo</code> set to the latest end date; otherwise the individual periods are returned. The <code>businessCaseTemplates</code> field is intentionally left empty on this endpoint — use <code>GET /core/v1/accounting/companies/current/business-case-templates</code> to retrieve the templates valid per period. Tenant and company are derived from the bearer token — there are no path or query parameters to override them. The endpoint is a pure read — idempotent, no side effects. The caller must hold the <code>ACCOUNTING</code> permission on the company in scope.",
        "parameters": [
          {
            "name": "Accept-Language",
            "in": "header",
            "description": "IETF language tag forwarded to the downstream accounting service. Examples: <code>de-CH</code>, <code>fr-CH</code>, <code>it-CH</code>, <code>en</code>.",
            "schema": {
              "type": "string",
              "example": "de-CH"
            },
            "example": "de-CH"
          }
        ],
        "responses": {
          "200": {
            "description": "Active financial-year periods of the caller's company. May be an empty array when the company has no open fiscal year yet.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/PublicApiBusinessCasePeriod"
                  }
                }
              }
            }
          },
          "401": {
            "description": "No Authorization header found or invalid token"
          },
          "403": {
            "description": "The current user is not allowed to access this company data",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "404": {
            "description": "The company associated with the caller's session could not be resolved by the downstream accounting service.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "429": {
            "description": "API rate limit exceeded"
          },
          "500": {
            "description": "Something went wrong on our side while processing the request. Please kindly contact our support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          }
        },
        "security": [
          {
            "apiKeyAuth": []
          },
          {
            "bearerAuth": []
          }
        ]
      }
    },
    "/core/v1/accounting/currencies/exchange-rate": {
      "get": {
        "tags": [
          "Accounting"
        ],
        "summary": "Get the CHF exchange rate for a currency on a given date.",
        "description": "Returns the Swiss National Bank reference rate that converts one unit of <code>from-currency-code</code> into CHF on <code>exchange-date</code>. When <code>from-currency-code</code> equals <code>CHF</code> (case-insensitive) the rate is always <code>1</code>. The exchange-rate table is global SNB data — the same response is returned for every tenant, so there are no tenant or company path parameters. If no rate is stored for the requested day, the downstream service transparently fetches the SNB feed for that date and persists the result; if the feed has no entry either, the most recent rate strictly before <code>exchange-date</code> is returned instead. The endpoint is a pure read for the caller — idempotent. Requires a bearer token whose principal carries the <code>ACCOUNTING</code> permission.",
        "parameters": [
          {
            "name": "exchange-date",
            "in": "query",
            "description": "Reference date for the exchange rate, expressed as an ISO-8601 calendar date (<code>yyyy-MM-dd</code>).",
            "required": true,
            "schema": {
              "format": "date",
              "type": "string",
              "example": "2024-09-30"
            },
            "example": "2024-09-30"
          },
          {
            "name": "from-currency-code",
            "in": "query",
            "description": "ISO-4217 alpha-3 currency code of the source amount. Case-insensitive; <code>CHF</code> short-circuits to a rate of <code>1</code>.",
            "required": true,
            "schema": {
              "type": "string",
              "example": "EUR"
            },
            "example": "EUR"
          }
        ],
        "responses": {
          "200": {
            "description": "Exchange rate as a JSON number; the value <code>1</code> when <code>from-currency-code</code> is CHF.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "number",
                  "example": 0.9421
                }
              }
            }
          },
          "400": {
            "description": "<code>exchange-date</code> is not a valid ISO-8601 calendar date, or no rate could be resolved for the supplied <code>from-currency-code</code>.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "401": {
            "description": "No Authorization header found or invalid token"
          },
          "429": {
            "description": "API rate limit exceeded"
          },
          "500": {
            "description": "Something went wrong on our side while processing the request. Please kindly contact our support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          }
        },
        "security": [
          {
            "apiKeyAuth": []
          },
          {
            "bearerAuth": []
          }
        ]
      }
    },
    "/core/v1/accounting/master-vats": {
      "get": {
        "tags": [
          "Accounting"
        ],
        "summary": "List the master VAT catalog used by Klara Accounting.",
        "description": "Returns the global master VAT catalog — the table of supported VAT rates with their validity ranges and translated labels. The downstream handler is a dispatcher driven by the query string: when <code>code</code> is non-blank only rows whose <code>vatCode</code> matches one of the semicolon-separated codes are returned (and when combined with <code>current-period=true</code>, only the ones valid today); otherwise when <code>default-vat=true</code> only the company-default rows are returned; otherwise the full catalog is returned, ordered by rate ascending, optionally paginated via <code>offset</code> / <code>limit</code>. Pagination is honoured only on the full-catalog branch — it is silently ignored when <code>code</code> or <code>default-vat</code> is set. The endpoint is a pure read and idempotent. Requires a bearer token whose principal carries the <code>ACCOUNTING_GET_MASTER_VAT</code> permission.",
        "parameters": [
          {
            "name": "code",
            "in": "query",
            "description": "Semicolon-separated list of <code>vatCode</code>s to filter on. When set, switches the response to the by-code branch and ignores <code>default-vat</code>.",
            "required": false,
            "schema": {
              "type": "string",
              "example": "1;3;4"
            },
            "example": "1;3;4"
          },
          {
            "name": "current-period",
            "in": "query",
            "description": "When combined with <code>code</code>, restricts the result to master VAT rows whose validity range covers today. Defaults to <code>false</code>.",
            "required": false,
            "schema": {
              "default": "false",
              "type": "boolean",
              "example": false
            },
            "example": false
          },
          {
            "name": "default-vat",
            "in": "query",
            "description": "When <code>true</code>, restricts the result to the company-default master VAT rows. Defaults to <code>false</code>. Ignored when <code>code</code> is set.",
            "required": false,
            "schema": {
              "default": "false",
              "type": "boolean",
              "example": false
            },
            "example": false
          },
          {
            "name": "includeHiddenVatCase",
            "in": "query",
            "description": "When <code>true</code>, the response also includes hidden VAT-case ids that are not directly mapped to a master VAT row. Defaults to <code>false</code>.",
            "required": false,
            "schema": {
              "default": "false",
              "type": "boolean",
              "example": false
            },
            "example": false
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Maximum number of results to return. Only honoured on the full-catalog branch.",
            "required": false,
            "schema": {
              "type": "integer",
              "example": 50
            },
            "example": 50
          },
          {
            "name": "offset",
            "in": "query",
            "description": "Zero-based index of the first result. Only honoured on the full-catalog branch (when neither <code>code</code> nor <code>default-vat</code> is set).",
            "required": false,
            "schema": {
              "type": "integer",
              "example": 0
            },
            "example": 0
          }
        ],
        "responses": {
          "200": {
            "description": "Array of master VAT rows matching the filters.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/PublicApiMasterVat"
                  }
                }
              }
            }
          },
          "401": {
            "description": "No Authorization header found or invalid token"
          },
          "429": {
            "description": "API rate limit exceeded"
          },
          "500": {
            "description": "Something went wrong on our side while processing the request. Please kindly contact our support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          }
        },
        "security": [
          {
            "apiKeyAuth": []
          },
          {
            "bearerAuth": []
          }
        ]
      }
    },
    "/core/v1/accounting/master-vats/{masterVatId}": {
      "get": {
        "tags": [
          "Accounting"
        ],
        "summary": "Resolve a master VAT catalog row by its numeric id.",
        "description": "Loads a single master VAT row from Klara's global master VAT catalog, identified by its numeric primary-key <code>masterVatId</code>. The catalog is global Klara reference data — the same row is returned for every tenant, so there are no tenant or company path parameters. The endpoint is a pure read and idempotent. Requires a bearer token whose principal carries the <code>ACCOUNTING_GET_MASTER_VAT</code> permission.",
        "parameters": [
          {
            "name": "masterVatId",
            "in": "path",
            "description": "Numeric primary-key id of the master VAT row to resolve. Obtain it from <code>GET /core/v1/accounting/master-vats</code> or <code>GET /core/v1/accounting/master-vats/current</code>.",
            "required": true,
            "schema": {
              "format": "int64",
              "type": "integer",
              "example": 12
            },
            "example": 12
          }
        ],
        "responses": {
          "200": {
            "description": "The master VAT row matching <code>masterVatId</code>, including its rate, VAT code and validity range.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiMasterVat"
                }
              }
            }
          },
          "401": {
            "description": "No Authorization header found or invalid token"
          },
          "404": {
            "description": "No master VAT row exists for the supplied <code>masterVatId</code>.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "429": {
            "description": "API rate limit exceeded"
          },
          "500": {
            "description": "Something went wrong on our side while processing the request. Please kindly contact our support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          }
        },
        "security": [
          {
            "apiKeyAuth": []
          },
          {
            "bearerAuth": []
          }
        ]
      }
    },
    "/core/v1/accounting/master-vats/current": {
      "get": {
        "tags": [
          "Accounting"
        ],
        "summary": "List the master VAT rows valid for today.",
        "description": "Returns the subset of the master VAT catalog whose validity range (<code>validFrom</code> / <code>validTo</code>) covers the server's current day. Useful for booking and invoicing UIs that need only the VAT rates that may legally be applied right now. The endpoint is a pure read and idempotent; the downstream handler caches the filtered list in-process. Requires a bearer token whose principal carries the <code>ACCOUNTING_GET_MASTER_VAT</code> permission.",
        "responses": {
          "200": {
            "description": "Array of master VAT rows valid for the current day.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/PublicApiMasterVat"
                  }
                }
              }
            }
          },
          "401": {
            "description": "No Authorization header found or invalid token"
          },
          "429": {
            "description": "API rate limit exceeded"
          },
          "500": {
            "description": "Something went wrong on our side while processing the request. Please kindly contact our support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          }
        },
        "security": [
          {
            "apiKeyAuth": []
          },
          {
            "bearerAuth": []
          }
        ]
      }
    },
    "/core/v1/accounting/vat-profile": {
      "get": {
        "tags": [
          "Accounting"
        ],
        "summary": "Get the authenticated company's VAT reporting profile.",
        "description": "Returns the company's VAT regime (effective vs net-tax-rate), billing method and flat net-tax rates, so an integration knows when the Saldosteuersatz flat-rate layer applies.",
        "parameters": [
          {
            "name": "date",
            "in": "query",
            "description": "Date (ISO yyyy-MM-dd) to resolve the company VAT config for; defaults to today. Use the date you intend to book on — the company VAT must be valid for it.",
            "schema": {
              "type": "string"
            },
            "example": "2025-05-08"
          }
        ],
        "responses": {
          "200": {
            "description": "VAT profile.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiVatProfile"
                }
              }
            }
          },
          "401": {
            "description": "No Authorization header found or invalid token"
          },
          "403": {
            "description": "The current user is not allowed to access this company data",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "500": {
            "description": "Something went wrong on our side while processing the request. Please kindly contact our support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          }
        },
        "security": [
          {
            "apiKeyAuth": []
          },
          {
            "bearerAuth": []
          }
        ]
      }
    },
    "/core/v1/accounting/vat-suggestions": {
      "get": {
        "tags": [
          "Accounting"
        ],
        "summary": "Suggest ready-to-use VAT case / rate / account bundles for a booking line.",
        "description": "Turns a plain-language context — a purchase vs a sale — into ranked, copy-paste-ready VAT bundles. Each bundle carries the verbatim <code>vatCaseLink</code> and <code>vatRateLink</code> to drop into a booking line's <code>links</code>, plus a suggested <code>vatAccountCode</code>. Supply <code>amount</code> to also receive a net/VAT preview. The bundle marked <code>recommended</code> is the server's best guess.<br/><br/><strong>Rebuilding the Manual-booking VAT UI from this response (read this if you are generating a UI).</strong> This endpoint returns a <em>flat array</em>, but the Manual-booking screen renders it as <strong>three linked dropdowns plus two toggles and an auto-computed amount</strong>. Map each control as follows:<table border=\"1\" cellpadding=\"4\"><tr><th>GUI control</th><th>Driven by</th><th>How to build it</th></tr><tr><td><strong>VAT</strong> on/off toggle</td><td>client-side state (not in this response)</td><td>OFF → the line has no VAT: don't call this endpoint, add no VAT links/fields. ON → call this endpoint and show the dropdowns below.</td></tr><tr><td><strong>VAT case</strong> dropdown (e.g. \"taxable supply\")</td><td>distinct <code>vatCaseCode</code> (label it with <code>label</code>)</td><td>Group the array by <code>vatCaseCode</code>; one entry per distinct case.</td></tr><tr><td><strong>VAT rate</strong> dropdown (e.g. \"8.1%\")</td><td><code>vatRateDisplay</code></td><td>Cascades from the chosen case: the rows sharing the selected <code>vatCaseCode</code> are the rate options.</td></tr><tr><td><strong>VAT account</strong> dropdown (e.g. \"1170 | Input tax VAT\")</td><td><code>vatAccountCodes</code></td><td>List all <code>vatAccountCodes</code>; preselect <code>vatAccountCode</code>.</td></tr><tr><td><strong>including / excluding</strong> toggle</td><td>the <code>amountKind</code> query param</td><td><code>including</code> = <code>GROSS_INCLUSIVE</code>; <code>excluding</code> = <code>NET_EXCLUSIVE</code>. Flipping it means re-calling this endpoint to refresh the preview.</td></tr><tr><td>Debit / Credit amount preview</td><td><code>previewNet</code> / <code>previewVat</code></td><td>Null until you pass <code>amount</code>. Re-call with the new <code>amount</code>/<code>amountKind</code> to refresh.</td></tr></table><strong>End-to-end recipe (call → render → book):</strong><ol><li>User turns the VAT toggle ON. Call this endpoint with <code>direction</code> (PURCHASE/SALE), the line's <code>accountCode</code>, the user's <code>amount</code>, the <code>amountKind</code> from the including/excluding toggle, and the <code>date</code> you will book on.</li><li>Render the dropdowns per the table above; preselect the row where <code>recommended = true</code>.</li><li>When the user picks a row, send it to <code>POST /core/v1/bookings?autoCalculateVat=true</code>: on the VAT-bearing line set <code>links = \"&lt;vatCaseLink&gt;,&lt;vatRateLink&gt;\"</code> (both verbatim), <code>vatAccountCode = &lt;vatAccountCode&gt;</code>, your <code>amount</code>, and <code>isExcludeVatAmount</code> matching the <code>amountKind</code> you queried — then omit the VAT counterpart line; the server generates it (matching <code>previewNet</code>/<code>previewVat</code>). Pass the same <code>date</code> you will book on.<br/><br/><strong>Coverage:</strong> the response mirrors the booking GUI's two dropdowns. The VAT-case list is direction-agnostic (every configured case is offered regardless of <code>direction</code>), and the rate list includes every configured version of each rate code the case references — current <em>and</em> historical — so a line dated before a rate change still finds its rate.",
        "parameters": [
          {
            "name": "accountCode",
            "in": "query",
            "description": "Main account being booked against (e.g. 1020); drives VAT-account resolution. Required.",
            "required": true,
            "schema": {
              "format": "int32",
              "type": "integer"
            },
            "example": 4000
          },
          {
            "name": "amount",
            "in": "query",
            "description": "Amount to preview the net/VAT split for (optional).",
            "schema": {
              "type": "number"
            },
            "example": 1000
          },
          {
            "name": "amountKind",
            "in": "query",
            "description": "GROSS_INCLUSIVE (default) or NET_EXCLUSIVE.",
            "schema": {
              "default": "GROSS_INCLUSIVE",
              "type": "string"
            },
            "example": "GROSS_INCLUSIVE"
          },
          {
            "name": "date",
            "in": "query",
            "description": "Date (ISO yyyy-MM-dd) to resolve the company VAT config for; defaults to today.",
            "schema": {
              "type": "string"
            },
            "example": "2025-05-08"
          },
          {
            "name": "direction",
            "in": "query",
            "description": "PURCHASE (you are buying) or SALE (you are selling). Required. It does not restrict which VAT cases are returned (the full case list is always offered); it only selects the fallback VAT account — purchases vs sales — and the recommendation wording.",
            "required": true,
            "schema": {
              "enum": [
                "PURCHASE",
                "SALE"
              ],
              "type": "string"
            },
            "example": "PURCHASE"
          },
          {
            "name": "vatCase",
            "in": "query",
            "description": "VAT case code to restrict suggestions to a single case; returns all its rate/account bundles (optional). Any valid case code is accepted regardless of direction — e.g. a sales case such as TAXABLE_SUPPLY can be requested with direction=PURCHASE.",
            "schema": {
              "enum": [
                "TAXABLE_SUPPLY",
                "SUPPLY_WITH_OPTION_ART_22",
                "TAX_EXEMPT_SUPPLY",
                "EXPORT",
                "SUPPLY_ABROAD",
                "EXCLUDED_SUPPLY",
                "DECREASE_IN_PROFITS",
                "INTERNAL_CONSUMPTION",
                "SUBVENTION",
                "CONTRIBUTIONS_DIVIDEND_DAMAGE_COMPENSION",
                "DOMESTIC_PURCHASE",
                "IMPORT_WITH_CUSTOMS",
                "IMPORT_WITH_REVERSE_CHARGE",
                "PURCHASE_ABROAD",
                "TRANSFER_SUPPLY",
                "MISCELLANEOUS",
                "DE_TAXATION",
                "MIXED_USE",
                "REDUCTION",
                "TAX_CREDIT_1050",
                "TAX_CREDIT_1055_1056"
              ],
              "type": "string"
            },
            "example": "DOMESTIC_PURCHASE"
          },
          {
            "name": "Accept-Language",
            "in": "header",
            "description": "Preferred language for the bundle labels.",
            "schema": {
              "type": "string"
            },
            "example": "de-CH"
          }
        ],
        "responses": {
          "200": {
            "description": "Ranked VAT suggestions.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/PublicApiVatSuggestion"
                  }
                },
                "examples": {
                  "Domestic purchase (accountCode=4000, amount=1000, GROSS_INCLUSIVE)": {
                    "description": "Four rows across two VAT cases: three DOMESTIC_PURCHASE rates (the recommended 8.1%, plus 3.8% and 2.6%) and one ACQUISITION_TAX case. Group by vatCaseCode to build the VAT-case dropdown; rows within a case are the VAT-rate options.",
                    "value": [
                      {
                        "label": "DOMESTIC_PURCHASE — 8.10%",
                        "recommended": false,
                        "vatCaseCode": "DOMESTIC_PURCHASE",
                        "vatCaseLink": "vat_case:/luz_accounting/api/vat-cases/5",
                        "vatRateDisplay": "8.10%",
                        "vatRateLink": "vat_rate:/luz_accounting/api/master-vats/58",
                        "vatAccountCode": 1171,
                        "previewNet": 925.07,
                        "previewVat": 74.93
                      },
                      {
                        "label": "DOMESTIC_PURCHASE — 3.80%",
                        "recommended": false,
                        "vatCaseCode": "DOMESTIC_PURCHASE",
                        "vatCaseLink": "vat_case:/luz_accounting/api/vat-cases/5",
                        "vatRateDisplay": "3.80%",
                        "vatRateLink": "vat_rate:/luz_accounting/api/master-vats/7",
                        "vatAccountCode": 1171,
                        "previewNet": 963.39,
                        "previewVat": 36.61
                      },
                      {
                        "label": "DOMESTIC_PURCHASE — 2.60%",
                        "recommended": false,
                        "vatCaseCode": "DOMESTIC_PURCHASE",
                        "vatCaseLink": "vat_case:/luz_accounting/api/vat-cases/5",
                        "vatRateDisplay": "2.60%",
                        "vatRateLink": "vat_rate:/luz_accounting/api/master-vats/56",
                        "vatAccountCode": 2203,
                        "previewNet": 974.66,
                        "previewVat": 25.34
                      },
                      {
                        "label": "DOMESTIC_PURCHASE — 8.10%",
                        "recommended": false,
                        "vatCaseCode": "DOMESTIC_PURCHASE",
                        "vatCaseLink": "vat_case:/luz_accounting/api/vat-cases/5",
                        "vatRateDisplay": "8.10%",
                        "vatRateLink": "vat_rate:/luz_accounting/api/master-vats/58",
                        "vatAccountCode": 2202,
                        "previewNet": 925.07,
                        "previewVat": 74.93
                      }
                    ]
                  }
                }
              }
            }
          },
          "400": {
            "description": "Data invalid",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "401": {
            "description": "No Authorization header found or invalid token"
          },
          "403": {
            "description": "The current user is not allowed to access this company data",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "500": {
            "description": "Something went wrong on our side while processing the request. Please kindly contact our support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          }
        },
        "security": [
          {
            "apiKeyAuth": []
          },
          {
            "bearerAuth": []
          }
        ]
      }
    },
    "/core/v1/accounting/vat-types": {
      "get": {
        "tags": [
          "Accounting"
        ],
        "summary": "List Klara master VAT-type catalogue rows.",
        "description": "Returns every VAT-type row maintained by Klara — the canonical VAT codes that can participate in a booking together with their posting formulas. The data is global — the same catalogue is returned for every tenant, so there are no tenant or company path parameters. The <code>Accept-Language</code> header selects which translation is used for the <code>description</code> and <code>vatTypeShortName</code> fields; if absent or unsupported, German is used as the fallback. The endpoint is a pure read — idempotent, no side effects. Any authenticated bearer token is accepted; the downstream service declares no role or permission requirement on this endpoint.",
        "parameters": [
          {
            "name": "Accept-Language",
            "in": "header",
            "description": "IETF language tag used to resolve the localized <code>description</code> and <code>vatTypeShortName</code> fields. Examples: <code>de-CH</code>, <code>fr-CH</code>, <code>it-CH</code>, <code>en</code>. When the header is missing or the language is unknown, the downstream service falls back to German.",
            "schema": {
              "type": "string",
              "example": "de-CH"
            },
            "example": "de-CH"
          }
        ],
        "responses": {
          "200": {
            "description": "Master VAT-type rows. Empty array when the catalogue has not been seeded yet.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/PublicApiVatType"
                  }
                }
              }
            }
          },
          "401": {
            "description": "No Authorization header found or invalid token"
          },
          "429": {
            "description": "API rate limit exceeded"
          },
          "500": {
            "description": "Something went wrong on our side while processing the request. Please kindly contact our support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          }
        },
        "security": [
          {
            "apiKeyAuth": []
          },
          {
            "bearerAuth": []
          }
        ]
      }
    },
    "/core/v1/accounting/vat-types/{vatTypeId}": {
      "get": {
        "tags": [
          "Accounting"
        ],
        "summary": "Resolve a Klara master VAT-type row by its numeric id.",
        "description": "Loads a single VAT-type row from Klara's global master VAT-type catalogue, identified by its numeric primary-key <code>vatTypeId</code>. The data is global — the same catalogue is shared across every tenant, so there are no tenant or company path parameters. The <code>Accept-Language</code> header selects which translation is used for the <code>description</code> and <code>vatTypeShortName</code> fields; if absent or unsupported, German is used as the fallback. The endpoint is a pure read — idempotent, no side effects. Any authenticated bearer token is accepted; the downstream service declares no role or permission requirement on this endpoint.",
        "parameters": [
          {
            "name": "vatTypeId",
            "in": "path",
            "description": "Numeric primary-key id of the master VAT-type row to resolve. Obtain it from <code>GET /core/v1/accounting/vat-types</code>.",
            "required": true,
            "schema": {
              "format": "int64",
              "type": "integer",
              "example": 1
            },
            "example": 1
          },
          {
            "name": "Accept-Language",
            "in": "header",
            "description": "IETF language tag used to resolve the localized <code>description</code> and <code>vatTypeShortName</code> fields. Examples: <code>de-CH</code>, <code>fr-CH</code>, <code>it-CH</code>, <code>en</code>. When the header is missing or the language is unknown, the downstream service falls back to German.",
            "schema": {
              "type": "string",
              "example": "de-CH"
            },
            "example": "de-CH"
          }
        ],
        "responses": {
          "200": {
            "description": "The master VAT-type row matching <code>vatTypeId</code>, including its localized description, short name and posting formulas.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiVatType"
                }
              }
            }
          },
          "401": {
            "description": "No Authorization header found or invalid token"
          },
          "404": {
            "description": "No master VAT-type row exists for the supplied <code>vatTypeId</code>.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "429": {
            "description": "API rate limit exceeded"
          },
          "500": {
            "description": "Something went wrong on our side while processing the request. Please kindly contact our support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          }
        },
        "security": [
          {
            "apiKeyAuth": []
          },
          {
            "bearerAuth": []
          }
        ]
      }
    },
    "/core/v1/bank-reconciliation/open-positions": {
      "get": {
        "tags": [
          "Accounting"
        ],
        "summary": "List the bank-reconciliation open positions of the authenticated company.",
        "description": "Returns the list of open booking-detail positions (AR / AP invoices, payments, prepayments, credit notes, general-ledger entries) of the caller's company that match the supplied filters, enriched with partner-name display, business-case message id, computed open amount and a stable booking-detail URI. Used by the bank-reconciliation UI to populate the open-position picker for a selected bank or credit-card transaction. The <code>action</code> parameter selects the multi-condition combinator: <code>search</code> (default) is OR-of-conditions, <code>filter</code> is AND-of-conditions. Tenant and company are derived from the bearer-token session — they are never accepted from the URL. The endpoint is a pure read — idempotent, no side effects. The caller must hold the <code>ACCOUNTING_GET_OPEN_POSITION</code> permission on the company in scope.",
        "parameters": [
          {
            "name": "action",
            "in": "query",
            "description": "Multi-condition combinator. <code>search</code> (default) = OR-of-conditions; <code>filter</code> = AND-of-conditions.",
            "required": false,
            "schema": {
              "default": "search",
              "enum": [
                "search",
                "filter"
              ],
              "type": "string",
              "example": "filter"
            },
            "example": "filter"
          },
          {
            "name": "booking-type-codes",
            "in": "query",
            "description": "Comma-separated list of booking-type codes to restrict to. Allowed values: <code>GENERAL_LEDGER</code>, <code>AP_INVOICE</code>, <code>AP_PAYMENT</code>, <code>AR_INVOICE</code>, <code>AR_PAYMENT</code>, <code>AP_PREPAYMENT</code>, <code>AP_PREPAYUSE</code>, <code>AR_PREPAYMENT</code>, <code>AR_PREPAYUSE</code>, <code>AR_CREDITNOTE</code>, <code>AR_CREDITUSE</code>, <code>AP_CREDITNOTE</code>, <code>AP_CREDITUSE</code>, <code>AMORTIZATION</code>, <code>SELLOFF_AMORTIZATION</code>, <code>DELIMIT</code>.",
            "required": false,
            "schema": {
              "type": "string",
              "example": "AR_PREPAYMENT,AR_CREDITNOTE"
            },
            "example": "AR_PREPAYMENT,AR_CREDITNOTE"
          },
          {
            "name": "crdr-type",
            "in": "query",
            "description": "Restrict to credit (<code>CR</code>) or debit (<code>DR</code>) postings.",
            "required": false,
            "schema": {
              "$ref": "#/components/schemas/PublicApiCrDrType"
            },
            "example": "CR"
          },
          {
            "name": "credit-card-not-reconciled",
            "in": "query",
            "description": "When <code>true</code>, restricts to credit-card transactions still pending reconciliation.",
            "required": false,
            "schema": {
              "type": "boolean",
              "example": true
            },
            "example": true
          },
          {
            "name": "general-search",
            "in": "query",
            "description": "Free-text search across description, partner name, document id and reference fields. Combined with the other filters using the mode selected by <code>action</code>.",
            "required": false,
            "schema": {
              "maxLength": 256,
              "type": "string",
              "example": "Migros"
            },
            "example": "Migros"
          },
          {
            "name": "invoice-date",
            "in": "query",
            "description": "Exact-match invoice (document) date filter (ISO date <code>yyyy-MM-dd</code>).",
            "required": false,
            "schema": {
              "format": "date",
              "type": "string",
              "example": "2026-04-15"
            },
            "example": "2026-04-15"
          },
          {
            "name": "partner",
            "in": "query",
            "description": "Klara partner URI to filter by. Format: <code>/api/luz_person/api/{tenantId}/companies/{companyId}/partners/{partnerId}</code>. Construct from the partner id returned by the public partner endpoints.",
            "required": false,
            "schema": {
              "type": "string",
              "example": "/api/luz_person/api/c60d31fa-f335-4957-872a-90b035632081/companies/1/partners/123"
            },
            "example": "/api/luz_person/api/c60d31fa-f335-4957-872a-90b035632081/companies/1/partners/123"
          },
          {
            "name": "payment-date",
            "in": "query",
            "description": "Exact-match payment date filter (ISO date <code>yyyy-MM-dd</code>).",
            "required": false,
            "schema": {
              "format": "date",
              "type": "string",
              "example": "2026-05-28"
            },
            "example": "2026-05-28"
          },
          {
            "name": "payment-date-from",
            "in": "query",
            "description": "Inclusive lower bound of the payment-date range filter (ISO date <code>yyyy-MM-dd</code>).",
            "required": false,
            "schema": {
              "format": "date",
              "type": "string",
              "example": "2026-01-01"
            },
            "example": "2026-01-01"
          },
          {
            "name": "payment-date-to",
            "in": "query",
            "description": "Inclusive upper bound of the payment-date range filter (ISO date <code>yyyy-MM-dd</code>).",
            "required": false,
            "schema": {
              "format": "date",
              "type": "string",
              "example": "2026-06-30"
            },
            "example": "2026-06-30"
          },
          {
            "name": "position-status",
            "in": "query",
            "description": "Comma-separated list of open-position lifecycle statuses to restrict to. Allowed values: <code>OPEN</code>, <code>PARTLY_PAID</code>, <code>PAID</code>, <code>PARTLY_CLEARED</code>, <code>CLEARED</code>.",
            "required": false,
            "schema": {
              "type": "string",
              "example": "OPEN,PARTLY_CLEARED"
            },
            "example": "OPEN,PARTLY_CLEARED"
          },
          {
            "name": "tags",
            "in": "query",
            "description": "Comma-separated list of tag names to filter by (free-form).",
            "required": false,
            "schema": {
              "maxLength": 256,
              "type": "string",
              "example": "vendor-x,q2"
            },
            "example": "vendor-x,q2"
          }
        ],
        "responses": {
          "200": {
            "description": "List of open positions matching the filters. Empty array when nothing matches.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/PublicApiSuitableOpenPosition"
                  }
                }
              }
            }
          },
          "400": {
            "description": "One of the date filters is not a valid ISO date (<code>yyyy-MM-dd</code>), or one of the enum filters (<code>position-status</code>, <code>booking-type-codes</code>, <code>crdr-type</code>) carries a value that is not in the documented value set, or a free-text filter exceeds 256 characters.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "401": {
            "description": "No Authorization header found or invalid token"
          },
          "403": {
            "description": "The current user is not allowed to access this company data",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "429": {
            "description": "API rate limit exceeded"
          },
          "500": {
            "description": "Something went wrong on our side while processing the request. Please kindly contact our support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          }
        },
        "security": [
          {
            "apiKeyAuth": []
          },
          {
            "bearerAuth": []
          }
        ]
      }
    },
    "/core/v1/bookings": {
      "post": {
        "tags": [
          "Accounting"
        ],
        "summary": "Create a new manual booking for the authenticated company.",
        "description": "Records a manual journal entry against the authenticated caller's company and returns the persisted booking with its server-assigned identifiers. The booking must contain at least two debit/credit lines whose totals balance — the downstream service rejects unbalanced postings. By default the <code>bookingDate</code> must fall inside an open fiscal year; set <code>confirmDontMindClosingFiscalYear</code> to <code>true</code> to accept a booking that targets a closing fiscal year. Set <code>ignore-unsubscripted-dates</code> to <code>true</code> to bypass the subscription-period guard that normally rejects bookings outside the active Klara Accounting subscription window. Tenant and company are derived from the bearer token — the request body's <code>id</code> and <code>companyId</code> are ignored. The caller must hold the <code>ACCOUNTING</code> permission on the targeted company.",
        "parameters": [
          {
            "name": "autoCalculateVat",
            "in": "query",
            "description": "When <code>true</code>, the server recalculates VAT like the Manual booking GUI: each VAT-bearing line sends a single gross/net <code>amount</code> + a <code>vat_rate</code> link + <code>vatAccountCode</code> + <code>isExcludeVatAmount</code> and <strong>omits</strong> its VAT counterpart line; the server derives the net/VAT split and generates the VAT line so the entry balances. When <code>false</code> (default), the caller must pre-split and pre-compute every line (current behaviour). Obtain valid VAT values from <code>GET /core/latest/vat-cases</code> and <code>GET /core/v1/accounting/master-vats</code>.",
            "schema": {
              "default": "false",
              "type": "boolean",
              "example": false
            },
            "example": false
          },
          {
            "name": "confirmDontMindClosingFiscalYear",
            "in": "query",
            "description": "When <code>true</code>, accept the booking even if its <code>bookingDate</code> falls in a closing fiscal year. Defaults to <code>false</code>.",
            "schema": {
              "default": "false",
              "type": "boolean",
              "example": false
            },
            "example": false
          },
          {
            "name": "ignore-unsubscripted-dates",
            "in": "query",
            "description": "When <code>true</code>, accept the booking even if its date falls outside the active Klara Accounting subscription period. Defaults to <code>false</code>.",
            "schema": {
              "default": "false",
              "type": "boolean",
              "example": false
            },
            "example": false
          },
          {
            "name": "Accept-Language",
            "in": "header",
            "description": "Preferred language for any localized error messages produced downstream. Examples: de-CH, fr-CH, it-CH, en. Defaults to the tenant's configured language when omitted.",
            "schema": {
              "type": "string",
              "example": "de-CH"
            },
            "example": "de-CH"
          }
        ],
        "requestBody": {
          "description": "The booking to create, including its at-least-two balanced debit/credit lines.<br/><br/><strong>Prerequisite APIs — call these first to obtain valid values:</strong><br/><ul><li><code>GET /core/v1/accounting/accounts</code> → provides valid <code>accountCode</code> values (e.g. 1020, 1100, 2000, 3200). Only use this endpoint when you want to implement a seperate combobox with a flat master account list without sub-account context.</li><li><code>GET /core/v1/accounting/accounts/account-displaying</code> → provide full details about all valid, selectable accounts (combine name, combine code, master account, sub-account details when available). <strong>PREFERRED</strong> to use this endpoint as the booking line for some account code <strong>MUST</strong> include sub-account links if the sub-account exists.</li><li><code>POST /core/latest/companies/{company-id}/documents</code> → upload supporting documents (invoices, receipts, bank statements) and collect the returned <code>documentId</code> values to populate <code>documentIds</code>. <strong>This step should be done BEFORE invoking the booking creation</strong>. <strong>Important:</strong> when calling this endpoint for booking creation, always use <code>category = LIABILITY_UPLOAD</code> — no other category is permitted in this context (the documents are automatically moved to <code>LIABILITIES</code> when the booking is created successfully). The GUI for booking creation must always provide a document-upload step using the <code>LIABILITY_UPLOAD</code> category.</li><li><code>GET /core/v1/accounting/booking-types</code> → provides valid <code>bookingTypeCode</code> values (e.g. AR_PAYMENT, AP_INVOICE, GENERAL_LEDGER)</li><li><code>GET /core/latest/vat-cases</code> → provides VAT case IDs for the <code>vat_case</code> link key</li><li><code>GET /core/v1/accounting/master-vats</code> → provides master VAT rate IDs for the <code>vat_rate</code> link key</li><li><code>GET /core/v1/accounting/vat-suggestions?direction=PURCHASE|SALE&amp;amount=…&amp;date=…</code> → <strong>RECOMMENDED for VAT.</strong> Returns ready-to-use bundles; from the <code>recommended</code> row copy <code>vatCaseLink</code> and <code>vatRateLink</code> straight into the line's <code>links</code> (comma-joined) and <code>vatAccountCode</code> onto the line. Use with <code>autoCalculateVat=true</code> (see VAT auto-calculation below).</li><li><code>GET /core/v1/accounting/vat-profile?date=…</code> → the company VAT regime (effective vs net-tax-rate). Informational: it explains how the server will split the amount; you do not copy it into the booking.</li></ul><strong>Top-level fields:</strong><br/><ul><li><code>id</code> (long) — Server-assigned. Set to <code>0</code> for new bookings.</li><li><code>companyId</code> (long) — Server-derived from token. Set to <code>0</code>.</li><li><code>bookingDate</code> (string, yyyy-MM-ddT00:00:00Z, <strong>required</strong>) — Must fall in an open fiscal year.</li><li><code>documentIds</code> (array of string) — IDs of attached documents (gather from <code>POST /core/latest/companies/{company-id}/documents</code> with <code>category = LIABILITY_UPLOAD</code>). The documents are automatically moved to <code>LIABILITIES</code> on success booking creation. <strong>A GUI implementing booking creation must always provide a document-upload step</strong> — omitting it is only acceptable for purely internal adjustments where no document exists, in which case <code>documentIds</code> may be left empty (<code>[]</code>).</li><li><code>internalComment</code> (string) — Internal note visible only to accounting users.</li><li><code>bookingStatus</code> (string) — Allowed: <code>DRAFT</code>, <code>BOOKED</code>, <code>CANCELLED</code>.</li><li><code>bookingDetails</code> (array, <strong>required</strong>) — At least 2 balanced debit/credit lines (see below).</li><li><code>expand</code> (boolean) — UI hint. Use <code>false</code>.</li><li><code>viewDocument</code> (boolean) — UI hint. Use <code>false</code>.</li></ul><strong>bookingDetails[] fields:</strong><br/><ul><li><code>id</code> (long) — Server-assigned. Set to <code>0</code>.</li><li><code>seq</code> (int) — Line order starting at 0.</li><li><code>accountCode</code> (int, <strong>required</strong>) — From <code>GET /core/v1/accounting/accounts</code> or <code>GET /core/v1/accounting/accounts/account-displaying</code> (preferred; includes sub-account context when it exists).</li><li><code>crdrType</code> (string, <strong>required</strong>) — <code>DR</code> (debit) or <code>CR</code> (credit).</li><li><code>description</code> (string) — Free-text line description.</li><li><code>amount</code> (decimal, <strong>required</strong>) — Always positive. Total DR must equal total CR.</li><li><code>tags</code> (string, <strong>required</strong>) — Comma-separated list of string tags. Each tag should represent a topic that the booking line should be associated with, e.g. Operating Expenses. Tags are free-form and have no semantic meaning to Klara; they are simply stored and returned as-is. Provide at least one tag per line.</li><li><code>links</code> (string) — Comma-separated structured links. Two uses: (a) sub-account entities for the line's account code (from <code>GET /core/v1/accounting/accounts/account-displaying</code>); and (b) VAT links <code>vat_case:…</code> + <code>vat_rate:…</code> (from <code>GET /core/v1/accounting/vat-suggestions</code>) when this line carries VAT. Can be empty when neither applies.</li><li><code>bookingTypeCode</code> (string) — From <code>GET /core/v1/accounting/booking-types</code>.</li><li><code>vatAccountCode</code> (int) — <strong>Only with <code>autoCalculateVat=true</code>.</strong> The account the generated VAT line posts to (e.g. 1170); from the <code>vatAccountCode</code> of a <code>vat-suggestions</code> row.</li><li><code>isExcludeVatAmount</code> (boolean) — <strong>Only with <code>autoCalculateVat=true</code>.</strong> <code>false</code> = <code>amount</code> includes VAT (gross); <code>true</code> = <code>amount</code> excludes VAT (net base).</li><li><code>isrReference</code> (string) — ISR/QR-bill reference. Empty if not applicable.</li><li><code>isrMember</code> (string) — ISR participant number. Empty if not applicable.</li><li><code>partnerIban</code> (string) — Counterpart IBAN for payments. Empty if not applicable.</li><li><code>vatBookingDetail</code> (boolean) — Set to <code>false</code> for manual lines.</li></ul><strong>VAT auto-calculation (<code>autoCalculateVat=true</code>) — book like the Manual booking GUI without doing VAT math:</strong><br/><ol><li>Call <code>GET /core/v1/accounting/vat-suggestions?direction=PURCHASE|SALE&amp;amount=&lt;gross&gt;&amp;date=&lt;bookingDate&gt;</code> and take the <code>recommended</code> row.</li><li>On the VAT-bearing line set: <code>links = \"&lt;vatCaseLink&gt;,&lt;vatRateLink&gt;\"</code> (both values verbatim from that row), <code>vatAccountCode = &lt;row.vatAccountCode&gt;</code>, <code>amount = &lt;your gross or net&gt;</code>, and <code>isExcludeVatAmount</code> matching the <code>amountKind</code> you queried (<code>false</code> = gross).</li><li><strong>Do NOT add the VAT counterpart line yourself</strong> — the server derives the net/VAT split and generates it (matching the row's <code>previewNet</code>/<code>previewVat</code>). Provide only your account line(s) + the balancing line.</li></ol>The split depends on the company VAT regime from <code>vat-profile</code> (effective → net + VAT line; net-tax-rate → flat-rate split; reverse-charge → an extra reverse VAT line). When <code>autoCalculateVat</code> is omitted/<code>false</code> you must instead pre-split and pre-compute every line yourself (see the \"Invoice received/sent\" examples).<br/><br/><strong>Rules:</strong> Minimum 2 lines; total DR = total CR (after server VAT expansion when <code>autoCalculateVat=true</code>); amounts always positive; bookingDate in open fiscal year.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PublicApiBookingHeader"
              },
              "examples": {
                "Money received": {
                  "description": "Customer pays an outstanding receivable via bank transfer (AR_PAYMENT). The bank line (1020) uses bank_account in links to identify the receiving bank sub-account.",
                  "value": {
                    "id": 0,
                    "companyId": 0,
                    "bookingDate": "2024-06-15T00:00:00Z",
                    "documentIds": [],
                    "internalComment": "Customer payment for invoice INV-2024-001",
                    "bookingStatus": "BOOKED",
                    "expand": false,
                    "viewDocument": false,
                    "bookingDetails": [
                      {
                        "id": 0,
                        "seq": 0,
                        "accountCode": 1020,
                        "crdrType": "DR",
                        "description": "Receipt from customer A. Bassi AG",
                        "amount": 1080,
                        "tags": "sales,project-alpha",
                        "links": "bank_account:/luzfin_finance/api/388c822c-7860-41ae-94ac-330684bb63e0/companies/1/bank-accounts/85",
                        "bookingTypeCode": "GENERAL_LEDGER",
                        "partnerIban": "CH5604835012345678009",
                        "isrReference": "",
                        "isrMember": "",
                        "vatBookingDetail": false
                      },
                      {
                        "id": 0,
                        "seq": 1,
                        "accountCode": 1100,
                        "crdrType": "CR",
                        "description": "Receipt from customer A. Bassi AG",
                        "amount": 1080,
                        "tags": "sales,project-alpha",
                        "links": "customer:/luzfin_finance/api/388c822c-7860-41ae-94ac-330684bb63e0/companies/1/customers/40",
                        "bookingTypeCode": "AR_PAYMENT",
                        "partnerIban": "",
                        "isrReference": "",
                        "isrMember": "",
                        "vatBookingDetail": false
                      }
                    ]
                  }
                },
                "Money sent": {
                  "description": "Outgoing QR-bill payment to a supplier (AP_PAYMENT). Includes ISR reference, ISR member number and partner IBAN on the payable line (2000). The bank line (1020) uses bank_account in links.",
                  "value": {
                    "id": 0,
                    "companyId": 0,
                    "bookingDate": "2024-06-15T00:00:00Z",
                    "documentIds": [],
                    "internalComment": "QR-bill payment to supplier — invoice SUP-2024-099",
                    "bookingStatus": "BOOKED",
                    "expand": false,
                    "viewDocument": false,
                    "bookingDetails": [
                      {
                        "id": 0,
                        "seq": 0,
                        "accountCode": 2000,
                        "crdrType": "DR",
                        "description": "Payment to supplier Müller GmbH",
                        "amount": 2500,
                        "tags": "supplier,office-supplies",
                        "links": "supplier:/luzfin_finance/api/388c822c-7860-41ae-94ac-330684bb63e0/companies/1/customers/37",
                        "bookingTypeCode": "AP_PAYMENT",
                        "partnerIban": "CH4431999123000889012",
                        "isrReference": "210000000003139471430009017",
                        "isrMember": "01-162-8",
                        "vatBookingDetail": false
                      },
                      {
                        "id": 0,
                        "seq": 1,
                        "accountCode": 1020,
                        "crdrType": "CR",
                        "description": "Payment to supplier Müller GmbH",
                        "amount": 2500,
                        "tags": "supplier,office-supplies",
                        "links": "bank_account:/luzfin_finance/api/388c822c-7860-41ae-94ac-330684bb63e0/companies/1/bank-accounts/85",
                        "bookingTypeCode": "GENERAL_LEDGER",
                        "partnerIban": "",
                        "isrReference": "",
                        "isrMember": "",
                        "vatBookingDetail": false
                      }
                    ]
                  }
                },
                "Invoice received": {
                  "description": "Supplier invoice posted with input-VAT split across 3 lines (AP_INVOICE). Material expense (4000) and VAT reclaim (1170) are debited; the full gross amount is credited to accounts payable (2000).",
                  "value": {
                    "id": 0,
                    "companyId": 0,
                    "bookingDate": "2024-06-15T00:00:00Z",
                    "documentIds": [],
                    "internalComment": "Office supplies invoice from supplier — ref SUP-2024-099",
                    "bookingStatus": "BOOKED",
                    "expand": false,
                    "viewDocument": false,
                    "bookingDetails": [
                      {
                        "id": 0,
                        "seq": 0,
                        "accountCode": 4000,
                        "crdrType": "DR",
                        "description": "Office supplies — net amount",
                        "amount": 925.93,
                        "tags": "office-supplies,q2",
                        "links": "",
                        "bookingTypeCode": "GENERAL_LEDGER",
                        "isrReference": "",
                        "isrMember": "",
                        "partnerIban": "",
                        "vatBookingDetail": false
                      },
                      {
                        "id": 0,
                        "seq": 1,
                        "accountCode": 1170,
                        "crdrType": "DR",
                        "description": "Office supplies — input VAT 8.1%",
                        "amount": 74.07,
                        "tags": "office-supplies,q2",
                        "links": "vat_case:/luz_accounting/api/vat-cases/1,vat_rate:/luz_accounting/api/master-vats/59",
                        "bookingTypeCode": "GENERAL_LEDGER",
                        "isrReference": "",
                        "isrMember": "",
                        "partnerIban": "",
                        "vatBookingDetail": true
                      },
                      {
                        "id": 0,
                        "seq": 2,
                        "accountCode": 2000,
                        "crdrType": "CR",
                        "description": "Office supplies — total payable",
                        "amount": 1000,
                        "tags": "office-supplies,q2",
                        "links": "supplier:/luzfin_finance/api/388c822c-7860-41ae-94ac-330684bb63e0/companies/1/customers/37",
                        "bookingTypeCode": "AP_INVOICE",
                        "isrReference": "",
                        "isrMember": "",
                        "partnerIban": "",
                        "vatBookingDetail": false
                      }
                    ]
                  }
                },
                "Invoice sent": {
                  "description": "Customer invoice posted with output-VAT split across 3 lines (AR_INVOICE). The full gross amount is debited to accounts receivable (1100); Revenue from deliveries and services (3000) and output VAT (2200) are credited.",
                  "value": {
                    "id": 0,
                    "companyId": 0,
                    "bookingDate": "2024-06-15T00:00:00Z",
                    "documentIds": [],
                    "internalComment": "Consulting services invoice to customer A. Bassi AG — ref INV-2024-001",
                    "bookingStatus": "BOOKED",
                    "expand": false,
                    "viewDocument": false,
                    "bookingDetails": [
                      {
                        "id": 0,
                        "seq": 0,
                        "accountCode": 1100,
                        "crdrType": "DR",
                        "description": "Consulting services — total receivable",
                        "amount": 1081,
                        "tags": "consulting,project-alpha",
                        "links": "customer:/luzfin_finance/api/388c822c-7860-41ae-94ac-330684bb63e0/companies/1/customers/40",
                        "bookingTypeCode": "AR_INVOICE",
                        "isrReference": "",
                        "isrMember": "",
                        "partnerIban": "",
                        "vatBookingDetail": false
                      },
                      {
                        "id": 0,
                        "seq": 1,
                        "accountCode": 3000,
                        "crdrType": "CR",
                        "description": "Consulting services — net revenue",
                        "amount": 1000,
                        "tags": "consulting,project-alpha",
                        "links": "",
                        "bookingTypeCode": "GENERAL_LEDGER",
                        "isrReference": "",
                        "isrMember": "",
                        "partnerIban": "",
                        "vatBookingDetail": false
                      },
                      {
                        "id": 0,
                        "seq": 2,
                        "accountCode": 2200,
                        "crdrType": "CR",
                        "description": "Consulting services — output VAT 8.1%",
                        "amount": 81,
                        "tags": "consulting,project-alpha",
                        "links": "vat_case:/luz_accounting/api/vat-cases/1,vat_rate:/luz_accounting/api/master-vats/58",
                        "bookingTypeCode": "GENERAL_LEDGER",
                        "isrReference": "",
                        "isrMember": "",
                        "partnerIban": "",
                        "vatBookingDetail": true
                      }
                    ]
                  }
                },
                "General ledger": {
                  "description": "Simple two-line accrual entry where all lines use GENERAL_LEDGER. Suitable for adjustments that do not involve AR, AP, or tax sub-ledgers.",
                  "value": {
                    "id": 0,
                    "companyId": 0,
                    "bookingDate": "2024-06-15T00:00:00Z",
                    "documentIds": [],
                    "internalComment": "Monthly accrual — prepaid insurance June 2024",
                    "bookingStatus": "BOOKED",
                    "expand": false,
                    "viewDocument": false,
                    "bookingDetails": [
                      {
                        "id": 0,
                        "seq": 0,
                        "accountCode": 1300,
                        "crdrType": "DR",
                        "description": "Prepaid insurance — June 2024",
                        "amount": 1200,
                        "tags": "insurance,accrual",
                        "links": "",
                        "bookingTypeCode": "GENERAL_LEDGER",
                        "isrReference": "",
                        "isrMember": "",
                        "partnerIban": "",
                        "vatBookingDetail": false
                      },
                      {
                        "id": 0,
                        "seq": 1,
                        "accountCode": 6000,
                        "crdrType": "CR",
                        "description": "Prepaid insurance — June 2024",
                        "amount": 1200,
                        "tags": "insurance,accrual",
                        "links": "",
                        "bookingTypeCode": "GENERAL_LEDGER",
                        "isrReference": "",
                        "isrMember": "",
                        "partnerIban": "",
                        "vatBookingDetail": false
                      }
                    ]
                  }
                },
                "Manual booking": {
                  "description": "Maximum-flexibility entry demonstrating all optional fields at once: bank sub-account (bank_account link), ISR reference, ISR member, partner IBAN, service period dates, and a pre-uploaded document attachment.",
                  "value": {
                    "id": 0,
                    "companyId": 0,
                    "bookingDate": "2024-06-15T00:00:00Z",
                    "documentDate": "2024-06-10",
                    "documentIds": [
                      "98765"
                    ],
                    "internalComment": "Manual correction — shows all optional fields",
                    "bookingStatus": "BOOKED",
                    "expand": false,
                    "viewDocument": false,
                    "bookingDetails": [
                      {
                        "id": 0,
                        "seq": 0,
                        "accountCode": 1020,
                        "crdrType": "DR",
                        "description": "Manual entry — bank side",
                        "amount": 500,
                        "tags": "manual,correction",
                        "links": "bank_account:/luzfin_finance/api/388c822c-7860-41ae-94ac-330684bb63e0/companies/1/bank-accounts/85",
                        "bookingTypeCode": "GENERAL_LEDGER",
                        "partnerIban": "CH5604835012345678009",
                        "isrReference": "210000000003139471430009017",
                        "isrMember": "01-162-8",
                        "servicePeriodFrom": "2024-06-01T00:00:00Z",
                        "servicePeriodTo": "2024-06-30T00:00:00Z",
                        "vatBookingDetail": false
                      },
                      {
                        "id": 0,
                        "seq": 1,
                        "accountCode": 3000,
                        "crdrType": "CR",
                        "description": "Manual entry — revenue side",
                        "amount": 500,
                        "tags": "manual,correction",
                        "links": "",
                        "bookingTypeCode": "GENERAL_LEDGER",
                        "partnerIban": "",
                        "isrReference": "",
                        "isrMember": "",
                        "vatBookingDetail": false
                      }
                    ]
                  }
                },
                "Post depreciation": {
                  "description": "Year-end straight-line asset depreciation (AMORTIZATION). Depreciation expense (6800) is debited; the accumulated-depreciation contra-asset account (1509) is credited with bookingTypeCode AMORTIZATION.",
                  "value": {
                    "id": 0,
                    "companyId": 0,
                    "bookingDate": "2024-12-31T00:00:00Z",
                    "documentIds": [],
                    "internalComment": "Annual depreciation — office equipment 2024",
                    "bookingStatus": "BOOKED",
                    "expand": false,
                    "viewDocument": false,
                    "bookingDetails": [
                      {
                        "id": 0,
                        "seq": 0,
                        "accountCode": 6800,
                        "crdrType": "DR",
                        "description": "Depreciation expense — office equipment 2024",
                        "amount": 3000,
                        "tags": "depreciation,fixed-assets",
                        "links": "financial_asset:/luz_accounting/api/388c822c-7860-41ae-94ac-330684bb63e0/companies/1/financial-asset/17",
                        "bookingTypeCode": "GENERAL_LEDGER",
                        "isrReference": "",
                        "isrMember": "",
                        "partnerIban": "",
                        "vatBookingDetail": false
                      },
                      {
                        "id": 0,
                        "seq": 1,
                        "accountCode": 1509,
                        "crdrType": "CR",
                        "description": "Accumulated depreciation — office equipment 2024",
                        "amount": 3000,
                        "tags": "depreciation,fixed-assets",
                        "links": "",
                        "bookingTypeCode": "AMORTIZATION",
                        "isrReference": "",
                        "isrMember": "",
                        "partnerIban": "",
                        "vatBookingDetail": false
                      }
                    ]
                  }
                },
                "VAT auto-calculation (autoCalculateVat=true)": {
                  "description": "Send with query param autoCalculateVat=true. The expense line (4000) carries the gross amount + vat_case/vat_rate links + vatAccountCode and OMITS the VAT line; the server splits it (925.93 net + 74.07 VAT to 1170) and balances against the payable (2000). Get the link values from GET /core/v1/accounting/vat-suggestions.",
                  "value": {
                    "id": 0,
                    "companyId": 0,
                    "bookingDate": "2024-06-15T00:00:00Z",
                    "documentIds": [],
                    "internalComment": "Office supplies — VAT auto-calculated by the server",
                    "bookingStatus": "BOOKED",
                    "expand": false,
                    "viewDocument": false,
                    "bookingDetails": [
                      {
                        "id": 0,
                        "seq": 0,
                        "accountCode": 4000,
                        "crdrType": "DR",
                        "description": "Office supplies — gross amount (VAT included)",
                        "amount": 1000,
                        "isExcludeVatAmount": false,
                        "links": "vat_case:/luz_accounting/api/vat-cases/1,vat_rate:/luz_accounting/api/master-vats/59",
                        "vatAccountCode": 1170,
                        "bookingTypeCode": "GENERAL_LEDGER",
                        "tags": "office-supplies",
                        "vatBookingDetail": false
                      },
                      {
                        "id": 0,
                        "seq": 1,
                        "accountCode": 2000,
                        "crdrType": "CR",
                        "description": "Total payable (gross)",
                        "amount": 1000,
                        "links": "",
                        "bookingTypeCode": "AP_INVOICE",
                        "tags": "office-supplies",
                        "vatBookingDetail": false
                      }
                    ]
                  }
                }
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Booking created.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicApiBookingHeader"
                }
              }
            }
          },
          "400": {
            "description": "Data invalid",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "401": {
            "description": "No Authorization header found or invalid token"
          },
          "403": {
            "description": "The current user is not allowed to access this company data",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "429": {
            "description": "API rate limit exceeded"
          },
          "500": {
            "description": "Something went wrong on our side while processing the request. Please kindly contact our support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          }
        },
        "security": [
          {
            "apiKeyAuth": []
          },
          {
            "bearerAuth": []
          }
        ]
      }
    },
    "/core/v1/bookings/{id}/documents": {
      "put": {
        "tags": [
          "Accounting"
        ],
        "summary": "Replace the document attachments and document date of an existing booking.",
        "description": "Replaces the set of supporting-document identifiers and the document date stored on an existing accounting booking. The operation is a full replacement &mdash; pass an empty <code>documentIds</code> array to clear all existing attachments, or omit <code>documentDate</code> / set it to <code>null</code> to clear it. By default the operation fails when the booking's existing <code>bookingDate</code> falls outside the active Klara Accounting subscription window; set <code>ignore-unsubscripted-dates</code> to <code>true</code> to bypass this guard. Tenant and company are derived from the bearer token &mdash; the booking <code>{id}</code> must belong to the caller's company. The caller must hold the <code>ACCOUNTING</code> permission on that company. The endpoint is idempotent: re-sending the same body produces the same state. Returns HTTP 200 with no body on success.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Internal id of the booking whose documents should be replaced. Obtain from the <code>id</code> field returned by <code>POST /core/v1/bookings</code>.",
            "required": true,
            "schema": {
              "format": "int64",
              "type": "integer",
              "example": 12345
            },
            "example": 12345
          },
          {
            "name": "ignore-unsubscripted-dates",
            "in": "query",
            "description": "When <code>true</code>, accept the update even if the booking's <code>bookingDate</code> falls outside the active Klara Accounting subscription period. Defaults to <code>false</code>.",
            "schema": {
              "default": "false",
              "type": "boolean",
              "example": false
            },
            "example": false
          }
        ],
        "requestBody": {
          "description": "Document metadata to apply to the booking. The operation is a full replacement of both <code>documentDate</code> and <code>documentIds</code>.<br/><br/><strong>Prerequisite APIs &mdash; call these first to obtain valid values:</strong><ul><li><code>POST /core/v1/bookings</code> &rarr; provides the booking <code>id</code> used in the URL.</li><li><code>POST /core/latest/companies/{company-id}/documents</code> &rarr; upload the file first and use the returned <code>documentId</code> as an entry in <code>documentIds</code>. Each entry is either a numeric Klara document id (e.g. <code>\"98765\"</code>) or a Klara document URI.</li></ul><strong>Top-level fields:</strong><ul><li><code>documentDate</code> (string, ISO date <code>yyyy-MM-dd</code>, optional) &mdash; date printed on the underlying paper document. Set to <code>null</code> or omit to clear the existing value.</li><li><code>documentIds</code> (array of string, optional, max 50 entries, each &le; 512 chars) &mdash; full replacement of the attached document references. Send <code>[]</code> to clear.</li></ul><strong>Rules:</strong><ul><li>Replacement semantics &mdash; missing or empty <code>documentIds</code> clears all existing attachments on the booking.</li><li>The booking must belong to the caller's company; tenant and company are derived from the bearer token.</li><li>By default the booking's existing <code>bookingDate</code> must fall in an active Klara Accounting subscription window; use <code>ignore-unsubscripted-dates=true</code> to bypass.</li></ul>",
          "content": {
            "application/json": {
              "schema": {
                "description": "Document metadata to attach to (or replace on) an existing accounting booking.",
                "type": "object",
                "properties": {
                  "documentDate": {
                    "format": "date",
                    "description": "Date printed on the underlying paper document (e.g. supplier invoice date). When omitted or null, the booking's existing documentDate is cleared.",
                    "type": "string",
                    "example": "2024-06-15"
                  },
                  "documentIds": {
                    "description": "Identifiers of supporting documents attached to the booking. Replaces the current set on the booking; pass an empty array to clear. Obtain each id by first uploading a file with POST /core/latest/companies/{company-id}/documents and then copying the returned documentId into this array.",
                    "maxItems": 50,
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "example": [
                      "98765"
                    ]
                  }
                },
                "example": {
                  "documentDate": "2024-06-15",
                  "documentIds": [
                    "98765"
                  ]
                }
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Document attachments and date applied to the booking (or accepted as a no-op when the booking does not exist on the downstream side)."
          },
          "400": {
            "description": "Data invalid",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "401": {
            "description": "No Authorization header found or invalid token"
          },
          "403": {
            "description": "The current user is not allowed to access this company data",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "429": {
            "description": "API rate limit exceeded"
          },
          "500": {
            "description": "Something went wrong on our side while processing the request. Please kindly contact our support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          }
        },
        "security": [
          {
            "apiKeyAuth": []
          },
          {
            "bearerAuth": []
          }
        ]
      }
    },
    "/core/v1/company-bank-accounts": {
      "get": {
        "tags": [
          "Finance"
        ],
        "summary": "List the bank accounts of the authenticated company.",
        "description": "Returns the bank accounts of the company resolved from the bearer JWT, optionally filtered by business <code>type</code>. The caller must hold the <code>FINANCE_BANK_ACCOUNT</code> permission on the target company. The result is sorted by Swiss-bank name then IBAN. This operation is idempotent and read-only — it can be safely retried.",
        "parameters": [
          {
            "name": "iban-number",
            "in": "query",
            "description": "Optional IBAN filter. When provided, the response contains the single matching bank account (returned as a one-element array for a uniform response shape) or HTTP 404 if no account exists with that IBAN. Spaces in the IBAN are tolerated. When provided, the <code>type</code> parameter is ignored.",
            "required": false,
            "schema": {
              "type": "string",
              "example": "CH7109000000252946932"
            },
            "example": "CH7109000000252946932"
          },
          {
            "name": "type",
            "in": "query",
            "description": "Optional business-type filter. Allowed values: <code>AR</code> (Accounts Receivable), <code>AP</code> (Accounts Payable), <code>HR</code> (Salary / HR payments). When omitted, all bank accounts are returned. Ignored when <code>iban-number</code> is provided.",
            "required": false,
            "schema": {
              "enum": [
                "AR",
                "AP",
                "HR"
              ],
              "type": "string",
              "example": "AR"
            },
            "example": "AR"
          }
        ],
        "responses": {
          "200": {
            "description": "Bank accounts of the authenticated company.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/CompanyBankAccount"
                  }
                }
              }
            }
          },
          "401": {
            "description": "No Authorization header found or invalid token"
          },
          "403": {
            "description": "The current user is not allowed to access this company data",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found"
          },
          "429": {
            "description": "API rate limit exceeded"
          },
          "500": {
            "description": "Something went wrong on our side while processing the request. Please kindly contact our support."
          }
        },
        "security": [
          {
            "apiKeyAuth": []
          },
          {
            "bearerAuth": []
          }
        ]
      }
    },
    "/core/v1/customers": {
      "get": {
        "tags": [
          "Customer"
        ],
        "summary": "Search and page the customers of the caller's company.",
        "description": "Returns a page of customers (<code>Persons</code> + <code>Companies</code>) of the caller's company, with optional free-text search (<code>search-key</code>) and status filter (<code>status</code>). Results are paged with <code>offset</code> and <code>limit</code>: to retrieve every customer, iterate <code>offset=0,&nbsp;limit,&nbsp;2&times;limit,&nbsp;…</code> until a response returns fewer than <code>limit</code> rows. All query parameters are optional; without any, the endpoint returns the first <code>50</code> active customers (downstream default ordering). This is a read-only, idempotent operation. <br/><br/>The tenant and company are derived from the JWT (<code>@CurrentSession Token</code>) and are never accepted as parameters. The caller must be authenticated (<code>apiKeyAuth</code> + <code>bearerAuth</code>) and must hold the <code>FINANCE_GET_CUSTOMER</code> permission on that company; otherwise the endpoint returns <code>403</code>.",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "description": "Page size. Defaults to <code>50</code>; hard cap <code>100</code>. Requests above the cap are rejected with <code>400</code>.",
            "schema": {
              "default": "50",
              "maximum": 100,
              "minimum": 1,
              "type": "integer",
              "example": 50
            }
          },
          {
            "name": "offset",
            "in": "query",
            "description": "0-based pagination offset — the number of customers to skip before the returned page. Defaults to <code>0</code>. Combine with <code>limit</code> to walk the full list.",
            "schema": {
              "default": "0",
              "minimum": 0,
              "type": "integer",
              "example": 0
            }
          },
          {
            "name": "search-key",
            "in": "query",
            "description": "Free-text search across customer <code>name</code>, <code>email</code>, <code>phone</code> and <code>customer number</code>. Tokenised on whitespace; matches are case-insensitive substring matches. Maximum length 256 characters.",
            "schema": {
              "maxLength": 256,
              "type": "string",
              "example": "müller"
            }
          },
          {
            "name": "status",
            "in": "query",
            "description": "Filter by customer state. Allowed values: <code>ACTIVE</code>, <code>ALL</code>, <code>ARCHIVED</code>. When omitted, the downstream service applies its default (active customers only).",
            "schema": {
              "maxLength": 16,
              "enum": [
                "ACTIVE",
                "ALL",
                "ARCHIVED"
              ],
              "type": "string",
              "example": "ACTIVE"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Customers",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Customer"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Data invalid",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "401": {
            "description": "No Authorization header found or invalid token"
          },
          "403": {
            "description": "The current user is not allowed to access this company data",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "429": {
            "description": "API rate limit exceeded"
          }
        },
        "security": [
          {
            "apiKeyAuth": []
          },
          {
            "bearerAuth": []
          }
        ]
      }
    },
    "/core/v1/employees/short-info": {
      "get": {
        "tags": [
          "Payroll"
        ],
        "summary": "List the company's employees as short-info entries, filtered and sorted.",
        "description": "Returns a lightweight directory of the authenticated company's employees (id, name, email, employee number, workplace, status), resolved from the compensation and person records. Each entry's <code>id</code> is the <code>employeeId</code> consumed by other employee-scoped endpoints (e.g. <code>GET /payroll/employees/{employeeId}/addable-salary-items</code>) — call this endpoint first to resolve an employee's id. Results can be narrowed with a free-text <code>search-key</code> (matched against name, employee number and email), restricted to specific workplaces via <code>workplace-ids</code>, and filtered by contract <code>filter-by-status</code>; ordering is controlled by <code>sort-field</code> and <code>sort-direction</code>. The tenant and company are derived from the authenticated token; the caller must hold the <code>COMPENSATION_TIME_TRACKING</code> permission on that company.",
        "parameters": [
          {
            "name": "filter-by-status",
            "in": "query",
            "description": "Contract-status filter. Allowed values: ALL, ACTIVE, INACTIVE, DRAFT. Defaults to ALL.",
            "required": false,
            "schema": {
              "description": "Contract-status filter. Allowed values: ALL, ACTIVE, INACTIVE, DRAFT. Defaults to ALL.",
              "default": "ALL",
              "enum": [
                "ALL",
                "ACTIVE",
                "INACTIVE",
                "DRAFT"
              ],
              "type": "string",
              "example": "ALL"
            },
            "example": "ALL"
          },
          {
            "name": "search-key",
            "in": "query",
            "description": "Case-insensitive substring matched against the employee's full name, employee number and email. When omitted, no text filter is applied.",
            "required": false,
            "schema": {
              "maxLength": 256,
              "type": "string"
            }
          },
          {
            "name": "sort-direction",
            "in": "query",
            "description": "Sort direction. Allowed values: ASC, DESC.",
            "required": false,
            "schema": {
              "$ref": "#/components/schemas/SortDirection"
            }
          },
          {
            "name": "sort-field",
            "in": "query",
            "description": "Field to sort by. Allowed values: NAME, EMAIL, EMPLOYEE_NUMBER. Defaults to NAME.",
            "required": false,
            "schema": {
              "description": "Field to sort the employee listing by. Allowed values: NAME, EMAIL, EMPLOYEE_NUMBER.",
              "default": "NAME",
              "enum": [
                "NAME",
                "EMAIL",
                "EMPLOYEE_NUMBER"
              ],
              "type": "string",
              "example": "NAME"
            },
            "example": "NAME"
          },
          {
            "name": "workplace-ids",
            "in": "query",
            "description": "Restrict results to employees whose current contract workplace is in this set. Repeat the parameter for multiple ids (e.g. workplace-ids=12&workplace-ids=13). When omitted, employees of all workplaces are returned.",
            "required": false,
            "schema": {
              "type": "array",
              "items": {
                "format": "int64",
                "type": "integer"
              }
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful operation",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/PublicApiEmployeeShortInfo"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Data invalid",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage1"
                }
              }
            }
          },
          "401": {
            "description": "No Authorization header found or invalid token"
          },
          "403": {
            "description": "The current user is not allowed to access this company data",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage1"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage1"
                }
              }
            }
          },
          "429": {
            "description": "API rate limit exceeded"
          },
          "500": {
            "description": "Something went wrong on our side while processing the request. Please kindly contact our support."
          }
        },
        "security": [
          {
            "apiKeyAuth": []
          },
          {
            "bearerAuth": []
          }
        ]
      }
    },
    "/core/v1/invoices": {
      "put": {
        "tags": [
          "Finance"
        ],
        "summary": "Update an existing DRAFT invoice for the authenticated company.",
        "description": "Updates a DRAFT invoice identified by <code>invoice.id</code> in the request body. Only invoices in <code>DRAFT</code> status can be updated — any other status returns 400. If the incoming <code>status</code> is <code>INVOICED</code> or <code>SENT</code>, the invoice is booked into KLARA accounting and inventory transactions are created, identical to the booking behavior of <code>POST /core/v1/invoices</code>. This is the call that finalizes a DRAFT — the GUI equivalent of posting in the final step; <strong>status is caller-controlled</strong>, so keep it <code>DRAFT</code> to re-save without booking. <strong>This endpoint does not send/deliver the invoice</strong> (no email/ePost/eBill/print&amp;send), regardless of <code>postMethod</code>; retrieve the PDF via <code>POST /core/v1/invoices/{id}/printed-document</code> and deliver it yourself. The caller must hold the <code>FINANCE</code> permission on the target company.<br/><br/><strong>Important — finalizing a DRAFT books it without a printed invoice.</strong> Setting <code>status=INVOICED</code>/<code>SENT</code> here creates the accounting booking but <strong>renders/stores no PDF</strong>. To attach the printed invoice to the booking, after this call run (1) <code>POST /core/v1/invoices/{id}/printed-document</code> to render and store the <code>printedFileId</code>, then (2) <code>PUT /core/v1/bookings/{id}/documents</code> to link that <code>printedFileId</code> (in <code>documentIds</code>) to the booking from <code>bookingNumbers</code>.",
        "parameters": [
          {
            "name": "confirmDontMindClosingFiscalYear",
            "in": "query",
            "description": "When <code>true</code>, allows save/booking even if the document date falls inside a closing or closed fiscal year. Defaults to false.",
            "schema": {
              "default": "false",
              "type": "boolean",
              "example": false
            },
            "example": false
          }
        ],
        "requestBody": {
          "description": "<strong>Updates an existing DRAFT invoice.</strong> The body structure is identical to <code>POST /core/v1/invoices</code> with one critical difference: <code>id</code> must be the numeric primary key of an existing invoice currently in <code>DRAFT</code> status.<br/><br/><strong>Typical flow:</strong><ol><li>Call <code>POST /core/v1/invoices</code> with <code>status=DRAFT</code> to create the invoice.</li><li>Call <code>GET /core/v1/invoices/{id}</code> to retrieve the current state.</li><li>Modify the desired fields (items, amounts, dates, etc.).</li><li>Call this endpoint to update — or to book it by changing <code>status</code> to <code>INVOICED</code>/<code>SENT</code>.</li></ol><strong>Prerequisite APIs (call these first if modifying related data):</strong><ul><li><code>GET /core/v1/invoices/{id}</code> → provides the current invoice body to modify and re-submit.</li><li><code>GET /core/v1/company-bank-accounts</code> → provides updated <code>ibanNumberCHF</code> / <code>ibanNumberCHW</code>.</li><li><code>GET /core/latest/articles/search?keyword=...</code> → search for articles to add/change order items.</li><li><code>GET /core/v1/bank-reconciliation/open-positions</code> → provides <code>openPositionsLinkedToInvoice[]</code> for reconciliation.</li><li><code>GET /core/latest/company-configuration/including-vat</code> → provides <code>usingVAT</code> default.</li></ul><br/><strong>Key differences from POST (create):</strong><ul><li><code>id</code> (long, required) — must be &gt; 0 and match an existing DRAFT invoice. Returns 400 if the stored invoice is not in DRAFT status.</li><li><code>invoiceCode</code> — uniqueness is NOT re-validated; retain the original value.</li><li><code>order.id</code> — must match the existing order; retain from the original invoice.</li><li><code>status</code> — set to <code>INVOICED</code> or <code>SENT</code> to book the invoice (triggers accounting); set to <code>DRAFT</code> to save without booking.</li></ul><br/><strong>Top-level fields:</strong><ul><li><code>id</code> (long, required) — must be &gt; 0 (existing DRAFT invoice id).</li><li><code>invoiceCode</code> (String, required) — must not be empty; retain the original value.</li><li><code>orderType</code> (String, required) — must be <code>INVOICE</code>.</li><li><code>status</code> (String, required) — <code>DRAFT</code> (saves without booking), <code>INVOICED</code> (saves and books into accounting), <code>SENT</code> (saves and books; does <strong>not</strong> send/deliver the invoice).</li><li><code>postMethod</code> (String, optional) — distribution channel recorded on the invoice only; not delivered. Allowed: <code>A_POST</code>, <code>B_POST</code>, <code>SEND_EMAIL</code>, <code>PRINT_AND_MANUAL_SEND</code>, <code>EPOST</code>, <code>EBILL</code>.</li><li><code>documentDate</code> (date, required) — invoice issue date, format <code>yyyy-MM-dd</code>; must fall inside the active subscription period.</li><li><code>paymentDate</code> (date, required when amount &gt; 0) — must be on or after <code>documentDate</code>.</li><li><code>ibanNumberCHF</code> (String, conditional) — CHF IBAN; format validated when provided.</li><li><code>ibanNumberCHW</code> (String, optional) — WIR IBAN; format validated when provided.</li><li><code>wirAcceptanceRate</code> (int, optional) — WIR acceptance percentage (0–100).</li><li><code>amount</code> (BigDecimal, required) — total invoice amount. Caller-supplied; not recomputed by the server.</li><li><code>usingVAT</code> (boolean) — GUI checkbox <em>\"VAT included in amount of each item\"</em>: item <code>price</code>/<code>amount</code> are VAT-inclusive (<code>true</code>, gross) or VAT-exclusive (<code>false</code>, net). It does <strong>not</strong> switch VAT on/off. Same VAT-handling rules as <code>POST /core/v1/invoices</code> (server stores amounts verbatim).</li><li><code>usingExportVat</code> (boolean, optional) — GUI checkbox <em>\"Export\"</em>; when <code>true</code> set every <code>orderItems[].vat.rate</code> to <code>0</code>. Defaults to <code>false</code>.</li><li><code>subject</code>, <code>ourReference</code>, <code>yourReference</code>, <code>companyCityAndDate</code>, <code>closeAndSignature</code> — optional text fields.</li></ul><br/><strong>Nested fields — <code>order</code> (required):</strong><ul><li><code>order.id</code> (long) — must be the existing order id; retain from the original invoice.</li><li><code>order.orderNumber</code> (int) — retain from the original invoice.</li><li><code>order.companyId</code> (long) — must match the authenticated company; set from bearer token on the downstream.</li><li><code>order.customer</code> (object, required) — existing customer; retain from original invoice.</li></ul><br/><strong>Nested fields — <code>orderItems[]</code> (required, at least 1):</strong><ul><li>Same structure as <code>POST /core/v1/invoices</code>. Existing item ids (&gt; 0) update items in-place; id = 0 adds new items.</li><li><code>orderItems[].tag</code> (String, required when booking) — must not be empty when status is <code>INVOICED</code>/<code>SENT</code>.</li></ul><br/><strong>Nested fields — <code>attachments[]</code> and <code>openPositionsLinkedToInvoice[]</code>:</strong><ul><li>Same structure and semantics as <code>POST /core/v1/invoices</code>.</li></ul><br/><strong>Validation rules:</strong><ul><li><code>id</code> must be &gt; 0 (adapter guard) and the stored invoice must be DRAFT (downstream guard).</li><li><code>paymentDate</code> must be on or after <code>documentDate</code> when amount &gt; 0.</li><li>IBAN format is validated when provided.</li><li>Each <code>orderItems[].tag</code> must be present when status triggers booking (<code>INVOICED</code>/<code>SENT</code>).</li><li>Subscription for Order Management must be active for <code>documentDate</code>.</li></ul><br/><strong>Server-managed fields (same as POST):</strong> <code>vatDate</code>, <code>lastModified</code>, <code>createDate</code>, <code>bookingDueDate</code>, <code>bookingNumbers</code>, <code>businessCaseId</code>, <code>bookingStatus</code>, <code>bookingMessage</code>, <code>bookingSealed</code>.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Invoice"
              },
              "examples": {
                "Update DRAFT to INVOICED": {
                  "summary": "Book an existing DRAFT invoice by changing status to INVOICED",
                  "value": {
                    "id": 42,
                    "invoiceCode": "123457736",
                    "paymentDate": "2026-06-28",
                    "ibanNumberCHF": "CH7109000000252946932",
                    "wirAcceptanceRate": 0,
                    "invoiceType": "MANUAL",
                    "order": {
                      "id": 55,
                      "orderNumber": 377,
                      "orderName": "Updated invoice",
                      "customer": {
                        "id": 40,
                        "company": {
                          "id": 34,
                          "name": "A. Bassi AG",
                          "emails": [
                            {
                              "id": "35",
                              "emailAddress": "chris.sutter@klara.ch",
                              "type": "PRIVATE"
                            }
                          ],
                          "addresses": [
                            {
                              "id": 280,
                              "companyName": "A. Bassi AG",
                              "type": "COMPANY",
                              "addressType": "WORK",
                              "street": "Ahornstrasse",
                              "homeNumber": "12",
                              "city": {
                                "id": 3713,
                                "addressPostcode": "8962",
                                "cityName18": "Bergdietikon"
                              }
                            }
                          ],
                          "language": "de"
                        },
                        "customerType": "COMPANY",
                        "termsOfPayment": 30
                      },
                      "companyId": 1
                    },
                    "status": "INVOICED",
                    "amount": 500,
                    "orderItems": [
                      {
                        "position": 1,
                        "itemNumer": "P0000061123",
                        "description": "Mobile Prepayment",
                        "quantity": 1,
                        "unit": "Unit",
                        "price": 500,
                        "discount": 0,
                        "vat": {
                          "vatCode": "1",
                          "rate": 5.3,
                          "description": "Reduced VAT rate",
                          "masterId": 42
                        },
                        "amount": 500,
                        "tag": "prepayment",
                        "vatCase": "TAXABLE_SUPPLY",
                        "articleType": "PREPAYMENT",
                        "id": 0
                      }
                    ],
                    "attachments": [],
                    "openPositionsLinkedToInvoice": [],
                    "subject": "Updated invoice",
                    "usingVAT": true,
                    "orderType": "INVOICE",
                    "documentDate": "2026-05-29",
                    "postMethod": "PRINT_AND_MANUAL_SEND"
                  }
                }
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Invoice updated successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Invoice"
                }
              }
            }
          },
          "400": {
            "description": "Data invalid",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "401": {
            "description": "No Authorization header found or invalid token"
          },
          "403": {
            "description": "The current user is not allowed to access this company data",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found"
          },
          "429": {
            "description": "API rate limit exceeded"
          },
          "500": {
            "description": "Something went wrong on our side while processing the request. Please kindly contact our support."
          }
        },
        "security": [
          {
            "apiKeyAuth": []
          },
          {
            "bearerAuth": []
          }
        ]
      },
      "post": {
        "tags": [
          "Finance"
        ],
        "summary": "Create a new KLARA invoice for the authenticated company.",
        "description": "Creates a new invoice for an existing customer under the company resolved from the bearer JWT. The request body's <code>id</code> must be <code>0</code> or omitted — this endpoint does not support updating existing invoices.<br/><br/><strong>Typical flow:</strong><ol><li>Call <code>GET /core/v1/invoices/next-invoice-number</code> to obtain the next invoice number.</li><li>Look up the customer via <code>GET /core/latest/customers</code> (with search filters).</li><li>Look up company bank accounts via <code>GET /core/v1/company-bank-accounts</code>.</li><li>Search articles via <code>GET /core/latest/articles/search</code> or <code>GET /core/latest/articles/article-numbers</code> to populate order items.</li><li>(Optional) Look up open positions via <code>GET /core/v1/bank-reconciliation/open-positions</code> to reconcile prepayments / credit notes.</li><li>(Optional) Call <code>POST /core/v1/orders/next-order-number</code> to obtain the next <code>order.orderNumber</code>.</li><li>(Optional) Call <code>GET /core/latest/company-configuration/including-vat</code> to determine the company default for <code>usingVAT</code>.</li><li>Build the invoice payload with order items.</li><li>Call this endpoint with <code>status=INVOICED</code> to save and book, or <code>status=DRAFT</code> to save without booking.</li></ol>On status <code>INVOICED</code> or <code>SENT</code> the invoice is also booked into KLARA accounting, inventory transactions are created and the HubSpot indicator is synchronised. <strong>This endpoint does not send/deliver the invoice</strong> (no email/ePost/eBill/print&amp;send), regardless of <code>postMethod</code> or a <code>SENT</code> status; retrieve the PDF via <code>POST /core/v1/invoices/{id}/printed-document</code> and deliver it yourself. The caller must hold the <code>FINANCE</code> permission on the target company.<br/><br/><strong>Status is caller-controlled.</strong> The Klara GUI keeps an invoice in <code>DRAFT</code> until the user posts it in the final step; via the API you choose — send <code>status=DRAFT</code> to save without booking, or <code>status=INVOICED</code> (or <code>SENT</code>) to book immediately. A DRAFT can be finalized later with <code>PUT /core/v1/invoices</code> (<code>status=INVOICED</code>).<br/><br/><strong>Important — booking is created without a printed invoice.</strong> When you book via this endpoint (<code>status=INVOICED</code>/<code>SENT</code>), the accounting booking is created but <strong>no PDF is rendered or stored</strong> — the invoice and its booking have no printed document (unlike the GUI, which renders, stores and books in one step). To attach the printed invoice, run two follow-up calls: (1) <code>POST /core/v1/invoices/{id}/printed-document</code> to render the PDF and store its <code>printedFileId</code> on the invoice, then (2) <code>PUT /core/v1/bookings/{id}/documents</code> to link that <code>printedFileId</code> (in <code>documentIds</code>) to the booking returned in <code>bookingNumbers</code>.",
        "parameters": [
          {
            "name": "confirmDontMindClosingFiscalYear",
            "in": "query",
            "description": "When <code>true</code>, allows save/booking even if the document date falls inside a closing or closed fiscal year. Defaults to false.",
            "schema": {
              "default": "false",
              "type": "boolean",
              "example": false
            },
            "example": false
          },
          {
            "name": "Accept-Language",
            "in": "header",
            "description": "Preferred response language as a BCP-47 tag (e.g. <code>en</code>, <code>de</code>, <code>fr</code>, <code>it</code>). Forwarded to luzfin_finance.",
            "schema": {
              "type": "string",
              "example": "en"
            },
            "example": "en"
          }
        ],
        "requestBody": {
          "description": "<strong>Creates a new invoice for an existing customer.</strong> The <code>id</code> field must be <code>0</code> or omitted. This endpoint does not support updating existing invoices.<br/><br/><strong>Prerequisite APIs (call these first):</strong><ul><li><code>GET /core/v1/invoices/next-invoice-number</code> → provides <code>invoiceCode</code> and <code>invoiceNumber</code> (the next available invoice number for the company).</li><li><code>GET /core/latest/customers?searchKey=...&amp;limit=...</code> → provides <code>order.customer.id</code>, <code>order.customer.company</code> (with addresses, emails), and <code>order.customer.customerType</code>.</li><li><code>GET /core/v1/company-bank-accounts</code> → provides <code>ibanNumberCHF</code> / <code>ibanNumberCHW</code> for payment accounts.</li><li><code>GET /core/latest/articles/search?keyword=...</code> → search articles by keyword for the autocomplete; provides <code>orderItems[].itemNumer</code>, <code>description</code>, <code>price</code>, <code>vat</code>, <code>unit</code>.</li><li><code>GET /core/latest/articles/article-numbers?article-numbers=...</code> → fetch full article data by article number(s) to fill <code>orderItems[]</code>.</li><li><code>GET /core/latest/articles/{article-id}/article-set-items</code> → expands article set/bundle into component line items for <code>orderItems[]</code>.</li><li><code>GET /core/v1/bank-reconciliation/open-positions</code> → lists customer's open prepayments / credit notes that can be reconciled; provides <code>openPositionsLinkedToInvoice[].bookingTypeCode</code>, <code>bookingDetailUri</code>, <code>partialPaymentAmount</code>.</li><li>(Optional) <code>POST /core/v1/orders/next-order-number</code> → provides <code>order.orderNumber</code>; each call advances the in-memory counter — call immediately before creating the invoice, not speculatively.</li><li>(Optional) <code>GET /core/latest/company-configuration/including-vat</code> → provides the company-level default for <code>usingVAT</code>; returns <code>false</code> when no configuration record exists.</li><li><code>printedFileId</code> (String, server-assigned) — populated automatically by <code>POST /core/v1/invoices/{id}/printed-document</code> after PDF generation; omit on creation.</li></ul><br/><strong>Top-level fields:</strong><ul><li><code>id</code> (long, required) — must be <code>0</code> for creation.</li><li><code>invoiceCode</code> (String, required) — unique invoice code; obtain from <code>GET /core/v1/invoices/next-invoice-number</code>.</li><li><code>orderType</code> (String, required) — must be <code>INVOICE</code>.</li><li><code>status</code> (String, required) — determines booking behavior (not delivery). Allowed: <code>DRAFT</code> (saves without booking), <code>INVOICED</code> (saves and books into accounting), <code>SENT</code> (saves and books; does <strong>not</strong> send/deliver the invoice).</li><li><code>postMethod</code> (String, optional) — distribution channel <strong>recorded on the invoice only</strong>; this endpoint does not deliver the invoice. Allowed: <code>A_POST</code>, <code>B_POST</code>, <code>SEND_EMAIL</code>, <code>PRINT_AND_MANUAL_SEND</code>, <code>EPOST</code>, <code>EBILL</code>.</li><li><code>documentDate</code> (date, required) — invoice issue date, format <code>yyyy-MM-dd</code>.</li><li><code>paymentDate</code> (date, required) — payment due date, must be on or after <code>documentDate</code>.</li><li><code>ibanNumberCHF</code> (String, conditional) — CHF IBAN for payment; required when booking is triggered.</li><li><code>ibanNumberCHW</code> (String, optional) — WIR IBAN for combined payments.</li><li><code>wirAcceptanceRate</code> (int, optional) — WIR acceptance percentage (0–100).</li><li><code>invoiceType</code> (String, required) — <code>MANUAL</code> or <code>RECURRING</code>.</li><li><code>amount</code> (BigDecimal, required) — total invoice amount over all items. Caller-supplied; not recomputed by the server. With <code>usingVAT=false</code> this is net + VAT; with <code>usingVAT=true</code> it is the sum of the gross item amounts.</li><li><code>usingVAT</code> (boolean) — GUI checkbox <em>\"VAT included in amount of each item\"</em>. Controls whether item <code>price</code>/<code>amount</code> are VAT-inclusive (<code>true</code>, gross) or VAT-exclusive (<code>false</code>, net). It does <strong>not</strong> switch VAT on/off (that is the company's VAT registration). Use <code>GET /core/latest/company-configuration/including-vat</code> for the company default. See <em>VAT handling</em> below.</li><li><code>usingExportVat</code> (boolean, optional) — GUI checkbox <em>\"Export\"</em>. When <code>true</code>, the invoice is an export: set every <code>orderItems[].vat.rate</code> to <code>0</code> so no VAT is charged. Defaults to <code>false</code>.</li><li><code>subject</code> (String, optional) — invoice subject/title.</li><li><code>ourReference</code> / <code>yourReference</code> (String, optional) — reference texts.</li><li><code>companyCityAndDate</code> (String, optional) — city and date line printed on invoice.</li><li><code>closeAndSignature</code> (String, optional) — closing text and signature block.</li><li><code>printedFileId</code> (String, optional) — document ID of uploaded PDF from partner system.</li></ul><br/><strong>Nested fields — <code>order</code> (required):</strong><ul><li><code>order.id</code> (long) — must be <code>0</code> for new orders.</li><li><code>order.orderNumber</code> (int, required) — unique order number; must be &gt; 0 (validated). Obtain from <code>POST /core/v1/orders/next-order-number</code> (not idempotent — each call advances the counter).</li><li><code>order.orderName</code> (String, optional) — order description.</li><li><code>order.companyId</code> (long, required) — company ID from bearer token scope.</li><li><code>order.customer</code> (object, required) — existing customer; obtain from <code>GET /core/v1/customers</code>. Must include <code>customer.id</code>, <code>customer.company</code> (with addresses), and <code>customer.customerType</code> (<code>COMPANY</code> or <code>PERSON</code>).</li></ul><br/><strong>Nested fields — <code>orderItems[]</code> (required, at least 1):</strong><ul><li><code>orderItems[].position</code> (int) — line item position (1-based).</li><li><code>orderItems[].itemNumer</code> (String) — article number.</li><li><code>orderItems[].description</code> (String) — item description.</li><li><code>orderItems[].quantity</code> (double) — quantity.</li><li><code>orderItems[].unit</code> (String) — unit of measure (e.g. <code>Unit</code>, <code>Hour</code>).</li><li><code>orderItems[].price</code> (double) — unit price (negative for credit notes). VAT-inclusive (gross) when <code>usingVAT=true</code>, VAT-exclusive (net) when <code>usingVAT=false</code>. Both variants are available from the article lookup APIs.</li><li><code>orderItems[].discount</code> (double) — discount percentage.</li><li><code>orderItems[].amount</code> (double) — line total = <code>quantity × price × (1 − discount/100)</code>, rounded to the nearest 0.05. Gross or net following <code>usingVAT</code> (same basis as <code>price</code>).</li><li><code>orderItems[].tag</code> (String, <strong>required for booking</strong>) — tags field; must not be empty when status is <code>INVOICED</code>/<code>SENT</code>.</li><li><code>orderItems[].vatCase</code> (String) — <code>TAXABLE_SUPPLY</code>, <code>EXEMPT_SUPPLY</code>, <code>REVERSE_CHARGE</code>.</li><li><code>orderItems[].articleType</code> (String) — <code>PRODUCTION</code>, <code>PREPAYMENT</code>, <code>SERVICE</code>.</li><li><code>orderItems[].vat</code> (object) — VAT details: <code>vatCode</code>, <code>rate</code>, <code>description</code>, <code>masterId</code>. For an export invoice (<code>usingExportVat=true</code>) set <code>rate=0</code> and the export/zero <code>vatCode</code>.</li><li><code>orderItems[].id</code> (long) — must be <code>0</code> for new items.</li></ul><br/><strong>VAT handling — the server does not recalculate amounts.</strong> Unlike the Klara GUI (which recomputes line amounts, VAT and totals whenever you toggle the <em>\"VAT included in amount of each item\"</em> or <em>\"Export\"</em> checkbox), this endpoint stores the amounts you send <em>verbatim</em> and performs no VAT recalculation or consistency check. Send <code>orderItems[].price</code>, <code>orderItems[].amount</code>, <code>orderItems[].vat</code> and the document <code>amount</code> already consistent with the two flags:<ul><li><code>usingVAT=false</code> (VAT-exclusive) — <code>price</code>/<code>amount</code> are net; document <code>amount</code> = net + VAT.</li><li><code>usingVAT=true</code> (VAT-inclusive) — <code>price</code>/<code>amount</code> are gross (VAT already inside); document <code>amount</code> = sum of gross item amounts.</li><li><code>usingExportVat=true</code> (export) — set every <code>orderItems[].vat.rate</code> to <code>0</code>; VAT = 0 and document <code>amount</code> = sum of net item amounts.</li></ul>To reproduce the GUI figures exactly: per line <code>amount = round0.05(quantity × price × (1 − discount/100))</code>; VAT per rate group = <code>amount × rate/100</code> when VAT-exclusive, or <code>amount × (rate/100) / (1 + rate/100)</code> when VAT-inclusive — each rounded to the nearest 0.05 (Swiss commercial rounding). Article unit prices for the inclusive, exclusive and export cases come from the article lookup APIs above (each article exposes both a VAT-inclusive and a VAT-exclusive price); pick the one matching <code>usingVAT</code>/<code>usingExportVat</code>.<br/><br/><strong>Nested fields — <code>attachments[]</code> (optional):</strong><ul><li><code>attachments[].fileId</code> (String) — document file ID uploaded via partner system.</li><li><code>attachments[].orderDetailId</code> (long) — set to <code>0</code> for new invoices.</li><li><code>attachments[].id</code> (long) — set to <code>0</code> for new attachments.</li></ul><br/><strong>Nested fields — <code>openPositionsLinkedToInvoice[]</code> (optional, for reconciliation):</strong><ul><li><code>openPositionsLinkedToInvoice[].bookingTypeCode</code> (String) — <code>AR_PREPAYMENT</code> or <code>AR_CREDITNOTE</code>.</li><li><code>openPositionsLinkedToInvoice[].bookingDetailUri</code> (String) — internal URI of the booking detail to reconcile (format: <code>/luz_accounting/api/{tenant-id}/companies/{companyId}/bookings/{bookingId}/booking-details/{detailId}</code>).</li><li><code>openPositionsLinkedToInvoice[].partialPaymentAmount</code> (BigDecimal) — amount to offset from this open position.</li></ul><br/><strong>Validation rules:</strong><ul><li><code>paymentDate</code> must be on or after <code>documentDate</code> (when amount &gt; 0).</li><li><code>order.orderNumber</code> must be &gt; 0.</li><li><code>invoiceCode</code> must be unique within the company.</li><li><code>status</code> must not be null.</li><li>IBAN format is validated when provided.</li><li>When status is <code>SENT</code>, credit notes (negative total) are not allowed.</li><li>Each <code>orderItems[].tag</code> must be present when status triggers booking (<code>INVOICED</code>/<code>SENT</code>).</li></ul><br/><strong>Server-managed fields (ignored on input, populated on output):</strong> <code>vatDate</code>, <code>lastModified</code>, <code>createDate</code>, <code>bookingDueDate</code>, <code>bookingNumbers</code>, <code>businessCaseId</code>, <code>bookingStatus</code>, <code>bookingMessage</code>, <code>bookingSealed</code>, <code>fiscalYearHasCreatedAuto</code>, <code>createBy</code>, <code>issuedDate</code>.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Invoice"
              },
              "examples": {
                "With articles only": {
                  "summary": "Create invoice with a list of items (articles)",
                  "value": {
                    "invoiceCode": "123457736",
                    "paymentDate": "2026-06-28",
                    "ibanNumberCHF": "CH7109000000252946932",
                    "wirAcceptanceRate": 0,
                    "invoiceType": "MANUAL",
                    "id": 0,
                    "order": {
                      "id": 0,
                      "orderNumber": 377,
                      "orderName": "Test create invoice",
                      "customer": {
                        "id": 40,
                        "company": {
                          "id": 34,
                          "name": "A. Bassi AG",
                          "emails": [
                            {
                              "id": "35",
                              "emailAddress": "chris.sutter@klara.ch",
                              "type": "PRIVATE"
                            }
                          ],
                          "addresses": [
                            {
                              "id": 280,
                              "companyName": "A. Bassi AG",
                              "type": "COMPANY",
                              "addressType": "WORK",
                              "street": "Ahornstrasse",
                              "homeNumber": "12",
                              "city": {
                                "id": 3713,
                                "addressPostcode": "8962",
                                "cityName18": "Bergdietikon"
                              }
                            }
                          ],
                          "language": "de"
                        },
                        "customerType": "COMPANY",
                        "termsOfPayment": 30
                      },
                      "companyId": 1
                    },
                    "status": "INVOICED",
                    "amount": 500,
                    "orderItems": [
                      {
                        "position": 1,
                        "itemNumer": "P0000061123",
                        "description": "Mobile Prepayment",
                        "quantity": 1,
                        "unit": "Unit",
                        "price": 500,
                        "discount": 0,
                        "vat": {
                          "vatCode": "1",
                          "rate": 5.3,
                          "description": "Reduced VAT rate",
                          "masterId": 42
                        },
                        "amount": 500,
                        "tag": "prepayment",
                        "vatCase": "TAXABLE_SUPPLY",
                        "articleType": "PREPAYMENT",
                        "id": 0
                      }
                    ],
                    "attachments": [],
                    "openPositionsLinkedToInvoice": [],
                    "subject": "Test create invoice",
                    "usingVAT": true,
                    "orderType": "INVOICE",
                    "documentDate": "2026-05-29",
                    "postMethod": "PRINT_AND_MANUAL_SEND"
                  }
                },
                "With articles and attachment": {
                  "summary": "Create invoice with items and a document attachment",
                  "value": {
                    "invoiceCode": "123457737",
                    "paymentDate": "2026-06-28",
                    "ibanNumberCHF": "CH7109000000252946932",
                    "wirAcceptanceRate": 0,
                    "invoiceType": "MANUAL",
                    "id": 0,
                    "order": {
                      "id": 0,
                      "orderNumber": 378,
                      "orderName": "Invoice with attachment",
                      "customer": {
                        "id": 40,
                        "company": {
                          "id": 34,
                          "name": "A. Bassi AG",
                          "emails": [
                            {
                              "id": "35",
                              "emailAddress": "chris.sutter@klara.ch",
                              "type": "PRIVATE"
                            }
                          ],
                          "addresses": [
                            {
                              "id": 280,
                              "companyName": "A. Bassi AG",
                              "type": "COMPANY",
                              "addressType": "WORK",
                              "street": "Ahornstrasse",
                              "homeNumber": "12",
                              "city": {
                                "id": 3713,
                                "addressPostcode": "8962",
                                "cityName18": "Bergdietikon"
                              }
                            }
                          ],
                          "language": "de"
                        },
                        "customerType": "COMPANY",
                        "termsOfPayment": 30
                      },
                      "companyId": 1
                    },
                    "status": "INVOICED",
                    "amount": 500,
                    "orderItems": [
                      {
                        "position": 1,
                        "itemNumer": "P0000061123",
                        "description": "Mobile Prepayment",
                        "quantity": 1,
                        "unit": "Unit",
                        "price": 500,
                        "discount": 0,
                        "vat": {
                          "vatCode": "1",
                          "rate": 5.3,
                          "description": "Reduced VAT rate",
                          "masterId": 42
                        },
                        "amount": 500,
                        "tag": "prepayment",
                        "vatCase": "TAXABLE_SUPPLY",
                        "articleType": "PREPAYMENT",
                        "id": 0
                      }
                    ],
                    "attachments": [
                      {
                        "orderDetailId": 0,
                        "fileId": "1771764",
                        "id": 0
                      }
                    ],
                    "openPositionsLinkedToInvoice": [],
                    "subject": "Invoice with attachment",
                    "usingVAT": true,
                    "orderType": "INVOICE",
                    "documentDate": "2026-05-29",
                    "postMethod": "PRINT_AND_MANUAL_SEND"
                  }
                },
                "With articles and reconciliation": {
                  "summary": "Create invoice with items and prepayment reconciliation",
                  "value": {
                    "invoiceCode": "123457738",
                    "paymentDate": "2026-06-28",
                    "ibanNumberCHF": "CH7109000000252946932",
                    "wirAcceptanceRate": 0,
                    "invoiceType": "MANUAL",
                    "id": 0,
                    "order": {
                      "id": 0,
                      "orderNumber": 383,
                      "orderName": "Invoice with reconciliation",
                      "customer": {
                        "id": 40,
                        "company": {
                          "id": 34,
                          "name": "A. Bassi AG",
                          "emails": [
                            {
                              "id": "35",
                              "emailAddress": "chris.sutter@klara.ch",
                              "type": "PRIVATE"
                            }
                          ],
                          "addresses": [
                            {
                              "id": 280,
                              "companyName": "A. Bassi AG",
                              "type": "COMPANY",
                              "addressType": "WORK",
                              "street": "Ahornstrasse",
                              "homeNumber": "12",
                              "city": {
                                "id": 3713,
                                "addressPostcode": "8962",
                                "cityName18": "Bergdietikon"
                              }
                            }
                          ],
                          "language": "de"
                        },
                        "customerType": "COMPANY",
                        "termsOfPayment": 30
                      },
                      "companyId": 1
                    },
                    "status": "INVOICED",
                    "amount": 1500,
                    "orderItems": [
                      {
                        "position": 1,
                        "itemNumer": "P0000061123",
                        "description": "Mobile Prepayment",
                        "quantity": 5,
                        "unit": "Unit",
                        "price": 500,
                        "discount": 0,
                        "vat": {
                          "vatCode": "1",
                          "rate": 5.3,
                          "description": "Reduced VAT rate",
                          "masterId": 42
                        },
                        "amount": 2500,
                        "tag": "prepayment",
                        "vatCase": "TAXABLE_SUPPLY",
                        "articleType": "PREPAYMENT",
                        "id": 0
                      },
                      {
                        "position": 2,
                        "itemNumer": "P0000061142",
                        "description": "Credit note",
                        "quantity": 1,
                        "unit": "Unit",
                        "price": -1000,
                        "discount": 0,
                        "vat": {
                          "vatCode": "1",
                          "rate": 5.3,
                          "description": "Reduced VAT rate",
                          "masterId": 42
                        },
                        "amount": -1000,
                        "tag": "tag",
                        "vatCase": "TAXABLE_SUPPLY",
                        "articleType": "PRODUCTION",
                        "id": 0
                      }
                    ],
                    "attachments": [],
                    "openPositionsLinkedToInvoice": [
                      {
                        "bookingTypeCode": "AR_PREPAYMENT",
                        "bookingDetailUri": "/luz_accounting/api/{tenant-id}/companies/1/bookings/1982/booking-details/11298",
                        "partialPaymentAmount": 500
                      },
                      {
                        "bookingTypeCode": "AR_PREPAYMENT",
                        "bookingDetailUri": "/luz_accounting/api/{tenant-id}/companies/1/bookings/1983/booking-details/11302",
                        "partialPaymentAmount": 500
                      }
                    ],
                    "subject": "Invoice with reconciliation",
                    "usingVAT": true,
                    "orderType": "INVOICE",
                    "documentDate": "2026-05-29",
                    "postMethod": "PRINT_AND_MANUAL_SEND"
                  }
                },
                "With articles, attachment and reconciliation": {
                  "summary": "Create invoice with items, attachment and prepayment reconciliation",
                  "value": {
                    "invoiceCode": "123457739",
                    "paymentDate": "2026-06-28",
                    "ibanNumberCHF": "CH7109000000252946932",
                    "wirAcceptanceRate": 0,
                    "invoiceType": "MANUAL",
                    "id": 0,
                    "order": {
                      "id": 0,
                      "orderNumber": 384,
                      "orderName": "Invoice with attachment and reconciliation",
                      "customer": {
                        "id": 40,
                        "company": {
                          "id": 34,
                          "name": "A. Bassi AG",
                          "emails": [
                            {
                              "id": "35",
                              "emailAddress": "chris.sutter@klara.ch",
                              "type": "PRIVATE"
                            }
                          ],
                          "addresses": [
                            {
                              "id": 280,
                              "companyName": "A. Bassi AG",
                              "type": "COMPANY",
                              "addressType": "WORK",
                              "street": "Ahornstrasse",
                              "homeNumber": "12",
                              "city": {
                                "id": 3713,
                                "addressPostcode": "8962",
                                "cityName18": "Bergdietikon"
                              }
                            }
                          ],
                          "language": "de"
                        },
                        "customerType": "COMPANY",
                        "termsOfPayment": 30
                      },
                      "companyId": 1
                    },
                    "status": "INVOICED",
                    "amount": 1500,
                    "orderItems": [
                      {
                        "position": 1,
                        "itemNumer": "P0000061123",
                        "description": "Mobile Prepayment",
                        "quantity": 5,
                        "unit": "Unit",
                        "price": 500,
                        "discount": 0,
                        "vat": {
                          "vatCode": "1",
                          "rate": 5.3,
                          "description": "Reduced VAT rate",
                          "masterId": 42
                        },
                        "amount": 2500,
                        "tag": "prepayment",
                        "vatCase": "TAXABLE_SUPPLY",
                        "articleType": "PREPAYMENT",
                        "id": 0
                      },
                      {
                        "position": 2,
                        "itemNumer": "P0000061142",
                        "description": "Credit note",
                        "quantity": 1,
                        "unit": "Unit",
                        "price": -1000,
                        "discount": 0,
                        "vat": {
                          "vatCode": "1",
                          "rate": 5.3,
                          "description": "Reduced VAT rate",
                          "masterId": 42
                        },
                        "amount": -1000,
                        "tag": "tag",
                        "vatCase": "TAXABLE_SUPPLY",
                        "articleType": "PRODUCTION",
                        "id": 0
                      }
                    ],
                    "attachments": [
                      {
                        "orderDetailId": 0,
                        "fileId": "1771764",
                        "id": 0
                      }
                    ],
                    "openPositionsLinkedToInvoice": [
                      {
                        "bookingTypeCode": "AR_PREPAYMENT",
                        "bookingDetailUri": "/luz_accounting/api/{tenant-id}/companies/1/bookings/1982/booking-details/11298",
                        "partialPaymentAmount": 500
                      },
                      {
                        "bookingTypeCode": "AR_PREPAYMENT",
                        "bookingDetailUri": "/luz_accounting/api/{tenant-id}/companies/1/bookings/1983/booking-details/11302",
                        "partialPaymentAmount": 500
                      }
                    ],
                    "subject": "Invoice with attachment and reconciliation",
                    "usingVAT": true,
                    "orderType": "INVOICE",
                    "documentDate": "2026-05-29",
                    "postMethod": "PRINT_AND_MANUAL_SEND"
                  }
                }
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Invoice persisted successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Invoice"
                }
              }
            }
          },
          "400": {
            "description": "Data invalid",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "401": {
            "description": "No Authorization header found or invalid token"
          },
          "403": {
            "description": "The current user is not allowed to access this company data",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found"
          },
          "429": {
            "description": "API rate limit exceeded"
          },
          "500": {
            "description": "Something went wrong on our side while processing the request. Please kindly contact our support."
          }
        },
        "security": [
          {
            "apiKeyAuth": []
          },
          {
            "bearerAuth": []
          }
        ]
      }
    },
    "/core/v1/invoices/{id}": {
      "get": {
        "tags": [
          "Finance"
        ],
        "summary": "Get a single invoice by its numeric id.",
        "description": "Returns the fully-enriched invoice document for the given <code>id</code> under the company resolved from the bearer JWT. The response includes order items enriched with inventory selection data and accounting booking-status fields (<code>bookingStatus</code>, <code>bookingDueDate</code>, <code>bookingSealed</code>) populated by <code>luz_accounting</code>. The caller must hold the <code>FINANCE</code> permission on the target company.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Numeric primary key of the invoice to retrieve. Obtain this from the <code>id</code> field of a previously created invoice (<code>POST /core/v1/invoices</code>).",
            "required": true,
            "schema": {
              "type": "integer",
              "example": 42
            },
            "example": 42
          }
        ],
        "responses": {
          "200": {
            "description": "Invoice found and returned.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Invoice"
                }
              }
            }
          },
          "401": {
            "description": "No Authorization header found or invalid token"
          },
          "403": {
            "description": "The current user is not allowed to access this company data",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "404": {
            "description": "No invoice with the given id exists for the authenticated company."
          },
          "429": {
            "description": "API rate limit exceeded"
          },
          "500": {
            "description": "Something went wrong on our side while processing the request. Please kindly contact our support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          }
        },
        "security": [
          {
            "apiKeyAuth": []
          },
          {
            "bearerAuth": []
          }
        ]
      }
    },
    "/core/v1/invoices/{id}/printed-document": {
      "post": {
        "tags": [
          "Finance"
        ],
        "summary": "Return the invoice as a PDF (rendering it if needed).",
        "description": "Returns the invoice document as a binary <code>application/pdf</code> stream via the internal Klara printing pipeline (<code>luz_web</code> + Aspose Words), mirroring the behaviour of the Klara GUI. The caller must hold the <code>FINANCE</code> permission on the target company.<br/><br/><strong>Reuse vs. render</strong> (mirrors the Klara GUI): if the invoice was already printed, the previously rendered PDF is fetched from storage and returned as-is; if it was not yet printed, it is rendered now and the <code>printedFileId</code> is stored on the invoice record. In both cases the response body is the binary PDF with a <code>Content-Disposition: attachment</code> header containing the suggested filename. This is a <code>POST</code> (not <code>GET</code>) because the first print persists the <code>printedFileId</code>.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "ID of the invoice to return as PDF. Must belong to the company resolved from the bearer JWT.",
            "required": true,
            "schema": {
              "type": "integer",
              "example": 42
            },
            "example": 42
          }
        ],
        "responses": {
          "200": {
            "description": "Invoice PDF returned as a binary <code>application/pdf</code> stream with a <code>Content-Disposition: attachment</code> header — either freshly rendered (first print) or the previously stored PDF (already printed).",
            "content": {
              "application/pdf": {}
            }
          },
          "401": {
            "description": "No Authorization header found or invalid token"
          },
          "403": {
            "description": "The current user is not allowed to access this company data",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "404": {
            "description": "Invoice not found."
          },
          "429": {
            "description": "API rate limit exceeded"
          },
          "500": {
            "description": "Something went wrong on our side while processing the request. Please kindly contact our support."
          }
        },
        "security": [
          {
            "apiKeyAuth": []
          },
          {
            "bearerAuth": []
          }
        ]
      }
    },
    "/core/v1/invoices/{id}/send": {
      "post": {
        "tags": [
          "Finance"
        ],
        "summary": "Send a booked invoice (smart delivery or a forced channel).",
        "description": "Sends an already-booked invoice to its recipient, synchronously, under the company resolved from the bearer JWT.<br/><br/>Omit <code>channel</code> for <strong>smart delivery</strong>: the system auto-routes through <code>EPOST</code>, <code>EBILL</code>, <code>SEND_EMAIL</code> and Print&amp;Send and only fails if none can deliver. Provide <code>channel</code> to <strong>force</strong> that exact channel: if the recipient is not eligible (e.g. no email on file, not eBill-registered, Print&amp;Send not subscribed) the call fails with 400. The invoice PDF is rendered on demand when it has not been printed yet.<br/><br/><strong>Prerequisites:</strong> the invoice must already be booked — <code>DRAFT</code> and cancelled invoices are rejected with 400. Create/book it via <code>POST /core/v1/invoices</code> (<code>status=INVOICED</code>) first.<br/><br/><strong>Not idempotent:</strong> each successful call performs a real delivery (sends an email / hands a letter to the postal channel) and overwrites the invoice's recorded post method — do not retry blindly on success.<br/><br/><code>channel</code> uses the same values as <code>Invoice.postMethod</code>, except <code>PRINT_AND_MANUAL_SEND</code>, which is not a deliverable channel and is rejected with 400. Authentication is API key + bearer JWT; the caller must hold the <code>FINANCE</code> permission on the target company.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Numeric primary key of the booked invoice to send. Must belong to the company resolved from the bearer JWT. Obtain it from the <code>id</code> of a previously created invoice (<code>POST /core/v1/invoices</code>).",
            "required": true,
            "schema": {
              "type": "integer",
              "example": 42
            },
            "example": 42
          },
          {
            "name": "channel",
            "in": "query",
            "description": "Forced distribution channel. <strong>Leave empty for smart delivery</strong> (auto-routing) — the default is no forced channel. Allowed values: <code>EPOST</code>, <code>EBILL</code>, <code>SEND_EMAIL</code>, <code>A_POST</code>, <code>B_POST</code>. <code>PRINT_AND_MANUAL_SEND</code> is rejected with 400 (not a deliverable channel).",
            "required": false,
            "schema": {
              "enum": [
                "A_POST",
                "B_POST",
                "SEND_EMAIL",
                "PRINT_AND_MANUAL_SEND",
                "EPOST",
                "EBILL"
              ],
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Invoice delivered. Returns the channel actually used, whether it was smart-routed, the OneAPI delivery id and the archived PDF's printedFileId.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SendInvoiceResult"
                }
              }
            }
          },
          "400": {
            "description": "Invoice is DRAFT/cancelled, the channel is unsupported (<code>PRINT_AND_MANUAL_SEND</code>), the recipient is not eligible for the forced channel, or smart delivery found no channel.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "401": {
            "description": "No Authorization header found or invalid token"
          },
          "403": {
            "description": "The current user is not allowed to access this company data",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "404": {
            "description": "No invoice with the given id exists for the authenticated company."
          },
          "429": {
            "description": "API rate limit exceeded"
          },
          "500": {
            "description": "Something went wrong on our side while processing the request. Please kindly contact our support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          }
        },
        "security": [
          {
            "apiKeyAuth": []
          },
          {
            "bearerAuth": []
          }
        ]
      }
    },
    "/core/v1/invoices/next-invoice-number": {
      "get": {
        "tags": [
          "Finance"
        ],
        "summary": "Get the next available invoice number for the authenticated company.",
        "description": "Returns the next available invoice number for the company resolved from the bearer JWT. The caller must hold the <code>FINANCE</code> permission on the target company. <strong>This operation is NOT idempotent</strong> — each successful call advances the persisted next-invoice-number counter on luzfin_finance, so the returned value is reserved and will not be returned again. Do not retry on success.",
        "responses": {
          "200": {
            "description": "Next available invoice number returned.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NextInvoiceNumberResponse"
                }
              }
            }
          },
          "401": {
            "description": "No Authorization header found or invalid token"
          },
          "403": {
            "description": "The current user is not allowed to access this company data",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found"
          },
          "429": {
            "description": "API rate limit exceeded"
          },
          "500": {
            "description": "Something went wrong on our side while processing the request. Please kindly contact our support."
          }
        },
        "security": [
          {
            "apiKeyAuth": []
          },
          {
            "bearerAuth": []
          }
        ]
      }
    },
    "/core/v1/order-documents/{order-type}/next-document-number": {
      "get": {
        "tags": [
          "Finance"
        ],
        "summary": "Get the next document number for a given order-document type.",
        "description": "Returns the next available sequence number and its formatted document code for the authenticated company and the given <code>order-type</code>. Use the returned <code>documentCode</code> as <code>invoiceCode</code> / <code>offerCode</code> when subsequently creating a document with <code>POST /core/v1/invoices</code>. <strong>Side effect for <code>INVOICE</code></strong>: the persisted counter is advanced on every call — do not call speculatively. Only meaningful for <code>OFFER</code>, <code>CONFIRMATION</code>, <code>DELIVERY_NOTE</code>, and <code>INVOICE</code>; other types always return <code>documentNumber = 0</code>. If the company has configured <code>MANUAL</code> numbering for the requested type, the downstream service returns HTTP 500 — check <code>GET /core/v1/order-numbering-configurations</code> first. The caller must hold the <code>FINANCE</code> permission on the target company.",
        "parameters": [
          {
            "name": "order-type",
            "in": "path",
            "description": "Order-document type whose counter to advance. Meaningful values: <code>OFFER</code>, <code>CONFIRMATION</code>, <code>DELIVERY_NOTE</code>, <code>INVOICE</code>. Other enum values (<code>CREDIT_NOTE</code>, <code>FRIENDLY_REMINDER</code>, <code>FIRST_REMINDER</code>, <code>SECOND_REMINDER</code>, <code>PAYSLIP</code>, <code>RECURRING_INVOICE_TEMPLATE</code>) are accepted but always return <code>documentNumber = 0</code>. An invalid value returns HTTP 400.",
            "required": true,
            "schema": {
              "description": "Order-management document type. Used as the discriminator on <code>OrderDocument.orderType</code>.",
              "enum": [
                "OFFER",
                "CONFIRMATION",
                "DELIVERY_NOTE",
                "INVOICE",
                "CREDIT_NOTE",
                "FRIENDLY_REMINDER",
                "FIRST_REMINDER",
                "SECOND_REMINDER",
                "PAYSLIP",
                "RECURRING_INVOICE_TEMPLATE"
              ],
              "type": "string",
              "example": "INVOICE",
              "nullable": false
            },
            "example": "INVOICE"
          }
        ],
        "responses": {
          "200": {
            "description": "Next document number and formatted code for the requested order type.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OrderNumberingResult"
                }
              }
            }
          },
          "400": {
            "description": "Data invalid",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "401": {
            "description": "No Authorization header found or invalid token"
          },
          "403": {
            "description": "The current user is not allowed to access this company data",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "429": {
            "description": "API rate limit exceeded"
          },
          "500": {
            "description": "Something went wrong on our side while processing the request. Please kindly contact our support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          }
        },
        "security": [
          {
            "apiKeyAuth": []
          },
          {
            "bearerAuth": []
          }
        ]
      }
    },
    "/core/v1/order-documents/filter/type-and-order-number": {
      "get": {
        "tags": [
          "Finance"
        ],
        "summary": "List order-management documents by type and order number.",
        "description": "Returns every order-management document of the company resolved from the bearer JWT that has the given <code>type</code> and business <code>order-number</code>. Used to discover sibling documents on the same order chain (e.g. find the <code>DELIVERY_NOTE</code>s for an order number before creating an <code>INVOICE</code> from them). The caller must hold the <code>FINANCE</code> permission on the target company. This operation is idempotent and read-only — it can be safely retried.",
        "parameters": [
          {
            "name": "order-number",
            "in": "query",
            "description": "Business order number shared by all documents in the same order chain (e.g. the <code>order.orderNumber</code> returned by <code>POST /core/v1/invoices</code>). Exact match. Required.",
            "required": true,
            "schema": {
              "type": "integer",
              "example": 377,
              "nullable": false
            },
            "example": 377
          },
          {
            "name": "type",
            "in": "query",
            "description": "Order-document type to filter by. Allowed values: <code>OFFER</code>, <code>CONFIRMATION</code>, <code>DELIVERY_NOTE</code>, <code>INVOICE</code>, <code>CREDIT_NOTE</code>, <code>FRIENDLY_REMINDER</code>, <code>FIRST_REMINDER</code>, <code>SECOND_REMINDER</code>, <code>PAYSLIP</code>, <code>RECURRING_INVOICE_TEMPLATE</code>. Required.",
            "required": true,
            "schema": {
              "description": "Order-management document type. Used as the discriminator on <code>OrderDocument.orderType</code>.",
              "enum": [
                "OFFER",
                "CONFIRMATION",
                "DELIVERY_NOTE",
                "INVOICE",
                "CREDIT_NOTE",
                "FRIENDLY_REMINDER",
                "FIRST_REMINDER",
                "SECOND_REMINDER",
                "PAYSLIP",
                "RECURRING_INVOICE_TEMPLATE"
              ],
              "type": "string",
              "example": "DELIVERY_NOTE",
              "nullable": false
            },
            "example": "DELIVERY_NOTE"
          }
        ],
        "responses": {
          "200": {
            "description": "Matching order-management documents.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/OrderDocument"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Data invalid",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "401": {
            "description": "No Authorization header found or invalid token"
          },
          "403": {
            "description": "The current user is not allowed to access this company data",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "429": {
            "description": "API rate limit exceeded"
          },
          "500": {
            "description": "Something went wrong on our side while processing the request. Please kindly contact our support."
          }
        },
        "security": [
          {
            "apiKeyAuth": []
          },
          {
            "bearerAuth": []
          }
        ]
      }
    },
    "/core/v1/order-numbering-configurations": {
      "get": {
        "tags": [
          "Finance"
        ],
        "summary": "Get the order-numbering configuration for a document type.",
        "description": "Returns the numbering strategy configured for the given <code>order-type</code> of the company resolved from the bearer JWT. Use this before creating a document to decide how to supply the document number in <code>POST /core/v1/invoices</code>: <code>STANDARD</code> — server auto-assigns; <code>MANUAL</code> — set <code>invoiceCode</code> yourself; <code>CUSTOMISED</code> — set <code>invoiceCode</code> to a value matching the returned <code>format</code> pattern. If no configuration has been saved by the company administrator, a default <code>STANDARD</code> configuration is returned. The caller must hold the <code>FINANCE</code> permission on the target company. This operation is idempotent and read-only.",
        "parameters": [
          {
            "name": "order-type",
            "in": "query",
            "description": "Document type to retrieve the numbering configuration for. Allowed values: <code>OFFER</code>, <code>CONFIRMATION</code>, <code>DELIVERY_NOTE</code>, <code>INVOICE</code>, <code>CREDIT_NOTE</code>, <code>FRIENDLY_REMINDER</code>, <code>FIRST_REMINDER</code>, <code>SECOND_REMINDER</code>, <code>PAYSLIP</code>, <code>RECURRING_INVOICE_TEMPLATE</code>. Recommended — omitting it returns a generic default with a null <code>orderType</code> field.",
            "required": false,
            "schema": {
              "description": "Order-management document type. Used as the discriminator on <code>OrderDocument.orderType</code>.",
              "enum": [
                "OFFER",
                "CONFIRMATION",
                "DELIVERY_NOTE",
                "INVOICE",
                "CREDIT_NOTE",
                "FRIENDLY_REMINDER",
                "FIRST_REMINDER",
                "SECOND_REMINDER",
                "PAYSLIP",
                "RECURRING_INVOICE_TEMPLATE"
              ],
              "type": "string",
              "example": "INVOICE"
            },
            "example": "INVOICE"
          }
        ],
        "responses": {
          "200": {
            "description": "Numbering configuration for the requested document type.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OrderNumberingConfiguration"
                }
              }
            }
          },
          "400": {
            "description": "Data invalid",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "401": {
            "description": "No Authorization header found or invalid token"
          },
          "403": {
            "description": "The current user is not allowed to access this company data",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "429": {
            "description": "API rate limit exceeded"
          },
          "500": {
            "description": "Something went wrong on our side while processing the request. Please kindly contact our support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          }
        },
        "security": [
          {
            "apiKeyAuth": []
          },
          {
            "bearerAuth": []
          }
        ]
      }
    },
    "/core/v1/orders/next-order-number": {
      "get": {
        "tags": [
          "Finance"
        ],
        "summary": "Get the next available order number for the authenticated company.",
        "description": "Returns the next available business order number for the company resolved from the bearer JWT. Use the returned <code>nextOrderNumber</code> as the <code>orderNumber</code> field when subsequently creating an order. <strong>Not idempotent</strong>: each call reserves and advances the in-memory counter — call this immediately before creating the order and do not call speculatively. Gaps may appear in the sequence if the subsequent order creation fails. The caller must hold the <code>FINANCE</code> permission on the target company.",
        "responses": {
          "200": {
            "description": "Next available order number for the authenticated company.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OrderNextNumberResult"
                }
              }
            }
          },
          "401": {
            "description": "No Authorization header found or invalid token"
          },
          "403": {
            "description": "The current user is not allowed to access this company data",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "429": {
            "description": "API rate limit exceeded"
          },
          "500": {
            "description": "Something went wrong on our side while processing the request. Please kindly contact our support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          }
        },
        "security": [
          {
            "apiKeyAuth": []
          },
          {
            "bearerAuth": []
          }
        ]
      }
    },
    "/core/v1/payroll/contracts/{contractId}/payslips/{payslipId}/salary-items": {
      "post": {
        "tags": [
          "Payroll"
        ],
        "summary": "Add a salary item to an employee's payslip.",
        "description": "Adds a single salary item (Base / Percent / Quantity / Amount / Comments) to the employee's editable (non-sealed) payslip identified by <code>payslipId</code>, then recalculates that month unless <code>recalculate=false</code>. Returns the added salary item with its server-assigned <code>id</code>. This operation is <strong>not idempotent</strong>: repeated calls append duplicate items or throw an error when the item is not duplicatable (subject to the item's duplicatable flag). <strong>Prerequisite:</strong> call <code>GET /payroll/employees/{employeeId}/addable-salary-items</code> first — its response provides the <code>contractId</code> and <code>payslipId</code> to target and the addable <code>code</code>s; resolve <code>employeeId</code> beforehand via <code>GET /employees/short-info</code>. The tenant and company are derived from the authenticated token; the caller must hold the <code>COMPENSATION</code> permission on that company.",
        "parameters": [
          {
            "name": "contractId",
            "in": "path",
            "description": "Id of the employee's contract to add the salary item to. Obtained from the <code>contractId</code> field of the <code>GET /payroll/employees/{employeeId}/addable-salary-items</code> response — call that endpoint first to select the employee and obtain this id.",
            "required": true,
            "schema": {
              "type": "integer",
              "example": 1
            },
            "example": 1
          },
          {
            "name": "payslipId",
            "in": "path",
            "description": "Id of the target (editable, non-sealed) payslip. Obtained from the <code>payslipId</code> field of the <code>GET /payroll/employees/{employeeId}/addable-salary-items</code> response — call that endpoint first to select the employee and obtain this id.",
            "required": true,
            "schema": {
              "type": "integer",
              "example": 26
            },
            "example": 26
          },
          {
            "name": "recalculate",
            "in": "query",
            "description": "Whether to recalculate the payslip after adding the item. Defaults to true.",
            "required": false,
            "schema": {
              "default": "true",
              "type": "boolean",
              "example": true
            },
            "example": true
          }
        ],
        "requestBody": {
          "description": "<strong>Purpose:</strong> add one salary item to the target payslip. The <code>code</code> must be one of the addable salary items for this payslip, and only the value fields the item allows may be sent.<br/><strong>Prerequisite APIs / value sources:</strong><ul><li><code>GET /employees/short-info</code> &rarr; provides <code>employeeId</code></li><li><code>GET /payroll/employees/{employeeId}/addable-salary-items</code> &rarr; provides the <code>contractId</code> and <code>payslipId</code> path parameters, plus <code>salaryItems[].code</code> (&rarr; <code>code</code>) and each item's <code>editableFields</code> (which of <code>baseValue</code>/<code>rate</code>/<code>quantity</code>/<code>value</code> may be sent)</li></ul><strong>Top-level fields:</strong><ul><li><code>code</code> (string, required) — salary-type code from the addable-salary-items response.</li><li><code>salaryItemValues</code> (object, optional) — the numeric values; see below.</li><li><code>remark</code> (string, optional, max 1024) — free-text comment (GUI \"Comments\").</li></ul><strong>Nested <code>salaryItemValues</code>:</strong><ul><li><code>baseValue</code> — GUI \"Base\".</li><li><code>rate</code> — GUI \"Percent (%)\", but expressed as a decimal <strong>multiplier</strong>, not a percentage number: <code>1</code> = 100%, <code>0.5</code> = 50%, <code>2</code> = 200%. If GUI implementation wants to keep a normal percentage input for the user (e.g. typing 50 for 50%), it must divide that value by 100 before sending it here (50 / 100 = 0.5).</li><li><code>quantity</code> — GUI \"Quantity\".</li><li><code>value</code> — GUI \"Amount\".</li></ul><strong>Rules:</strong> the payslip must be editable (non-sealed); the <code>code</code> must be addable to this payslip (returned by the addable-salary-items endpoint); only fields listed in the item's <code>editableFields</code> should be provided and the GUI implementation should also only show input boxes for those fields; with salary items that are not duplicatable (<code>duplicatable=false</code>), the GUI implementation should have a mechanism to recall the <code>GET /payroll/employees/{employeeId}/addable-salary-items</code> endpoint after each add to refresh the list of addable items and prevent adding duplicates, or automatically remove the added item from the list of addable items in the GUI; <code>salaryItemValues.rate</code> is a decimal multiplier (1 = 100%, 0.5 = 50%, 2 = 200%), not a percentage number — do not send a raw percentage like 50 for 50%, send 0.5.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PayslipSalaryItemRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Successful operation",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PayslipSalaryItem"
                }
              }
            }
          },
          "400": {
            "description": "Data invalid",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage1"
                }
              }
            }
          },
          "401": {
            "description": "No Authorization header found or invalid token"
          },
          "403": {
            "description": "The current user is not allowed to access this company data",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage1"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage1"
                }
              }
            }
          },
          "429": {
            "description": "API rate limit exceeded"
          },
          "500": {
            "description": "Something went wrong on our side while processing the request. Please kindly contact our support."
          }
        },
        "security": [
          {
            "apiKeyAuth": []
          },
          {
            "bearerAuth": []
          }
        ]
      }
    },
    "/core/v1/payroll/employees/{employeeId}/addable-salary-items": {
      "get": {
        "tags": [
          "Payroll"
        ],
        "summary": "Get the salary items that can be added to an employee's payslip.",
        "description": "Resolves the employee's main (latest) contract and its editable payslip, then returns the salary-item types that can be added to that payslip as blank templates (numeric value fields cleared, distinct by <code>code</code>), together with the resolved <code>contractId</code> and <code>payslipId</code> so the response can be chained into the add-salary-item call. <strong>Prerequisite:</strong> call <code>GET /employees/short-info</code> first to resolve the <code>employeeId</code> path parameter from the returned entries' <code>id</code> field. When <code>month</code> is provided the specified month's payslip is used (read-only); when it is omitted the employee's current editable payslip is used, which may be computed on first access. The tenant and company are derived from the authenticated token; the caller must hold the <code>COMPENSATION</code> permission on that company.",
        "parameters": [
          {
            "name": "employeeId",
            "in": "path",
            "description": "Id of the employee whose addable salary items are resolved. Obtained from the <code>id</code> field of an entry returned by <code>GET /employees/short-info</code>.",
            "required": true,
            "schema": {
              "type": "integer",
              "example": 1
            },
            "example": 1
          },
          {
            "name": "month",
            "in": "query",
            "description": "Payslip month in the format MM.yyyy (e.g. 06.2025). If omitted, the employee's current editable payslip is used.",
            "required": false,
            "schema": {
              "type": "string",
              "example": "06.2025"
            },
            "example": "06.2025"
          },
          {
            "name": "Accept-Language",
            "in": "header",
            "description": "Preferred language for localised salary-item descriptions, as an IETF language tag. Examples: de-CH, fr-CH, it-CH, en. Defaults to the tenant's language when omitted.",
            "schema": {
              "type": "string",
              "example": "de-CH"
            },
            "example": "de-CH"
          }
        ],
        "responses": {
          "200": {
            "description": "Successful operation",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AddablePayslipSalaryItems"
                }
              }
            }
          },
          "400": {
            "description": "Data invalid",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage1"
                }
              }
            }
          },
          "401": {
            "description": "No Authorization header found or invalid token"
          },
          "403": {
            "description": "The current user is not allowed to access this company data",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage1"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage1"
                }
              }
            }
          },
          "429": {
            "description": "API rate limit exceeded"
          },
          "500": {
            "description": "Something went wrong on our side while processing the request. Please kindly contact our support."
          }
        },
        "security": [
          {
            "apiKeyAuth": []
          },
          {
            "bearerAuth": []
          }
        ]
      }
    },
    "/core/v1/vat-clearing-reports/{year}/{quarter}": {
      "post": {
        "tags": [
          "Accounting"
        ],
        "summary": "Get or recompute the VAT clearing report of a company for a given period.",
        "description": "Returns the VAT clearing report of the caller's company for the requested calendar <code>year</code> and reporting <code>quarter</code> (quarter, semester or yearly). When <code>recalculate=true</code> the report is recomputed from the current bookings and the stored <code>CALCULATED</code> snapshot is rewritten before being returned; this is why the operation uses <code>POST</code> rather than <code>GET</code>. When <code>recalculate=false</code> the latest <code>CALCULATED</code> snapshot is returned as-is, or — if only a <code>SEALED</code> snapshot exists — that one. The caller must hold the <code>ACCOUNTING</code> permission on the targeted company.",
        "parameters": [
          {
            "name": "quarter",
            "in": "path",
            "description": "Reporting period within the year. Allowed values: Q1, Q2, Q3, Q4, S1, S2, YEAR_NET_TAX_RATE, YEAR_EFFECTIVE.",
            "required": true,
            "schema": {
              "description": "Reporting period of a VAT clearing report.",
              "enum": [
                "Q1",
                "Q2",
                "Q3",
                "Q4",
                "S1",
                "S2",
                "YEAR_NET_TAX_RATE",
                "YEAR_EFFECTIVE"
              ],
              "type": "string",
              "example": "Q1"
            },
            "example": "Q1"
          },
          {
            "name": "year",
            "in": "path",
            "description": "Calendar year of the reporting period.",
            "required": true,
            "schema": {
              "type": "integer",
              "example": 2024
            },
            "example": 2024
          },
          {
            "name": "recalculate",
            "in": "query",
            "description": "If true, recompute the report from current bookings and overwrite the stored CALCULATED snapshot before returning. Defaults to false.",
            "required": false,
            "schema": {
              "default": "false",
              "type": "boolean",
              "example": false
            },
            "example": false
          },
          {
            "name": "Accept-Language",
            "in": "header",
            "description": "Preferred language for localized labels in the response. Examples: de-CH, de, fr-CH, it-CH, en.",
            "required": false,
            "schema": {
              "type": "string",
              "example": "de-CH"
            },
            "example": "de-CH"
          }
        ],
        "responses": {
          "200": {
            "description": "The VAT clearing report.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VatClearingReport"
                }
              }
            }
          },
          "401": {
            "description": "No Authorization header found or invalid token"
          },
          "403": {
            "description": "The current user is not allowed to access this company data",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found"
          },
          "429": {
            "description": "API rate limit exceeded"
          },
          "500": {
            "description": "Something went wrong on our side while processing the request. Please kindly contact our support."
          }
        },
        "security": [
          {
            "apiKeyAuth": []
          },
          {
            "bearerAuth": []
          }
        ]
      }
    },
    "/core/v2/tenants/companies": {
      "get": {
        "tags": [
          "Company"
        ],
        "summary": "Find KLARA business company of tenant",
        "description": "Retrieve the business company of a tenant. Use your KLARA token from your username & password & tenant-id.",
        "responses": {
          "201": {
            "description": "Company found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BusinessCompany"
                }
              }
            }
          },
          "401": {
            "description": "Invalid credentials",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "The user has been disabled",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "API rate limit exceeded"
          },
          "500": {
            "description": "Something went wrong when find company",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "apiKeyAuth": []
          },
          {
            "bearerAuth": []
          }
        ]
      },
      "put": {
        "tags": [
          "Company"
        ],
        "summary": "Update a KLARA business company",
        "description": "A Klara user might have multiple tenants. Use this endpoint to update a KLARA business company. Use your KLARA token from your username & password & tenant-id.",
        "requestBody": {
          "description": "The updated company information",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BusinessCompany"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Company updated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BusinessCompany"
                }
              }
            }
          },
          "400": {
            "description": "Invalid company data",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Invalid credentials",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "The user has been disabled",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "API rate limit exceeded"
          },
          "500": {
            "description": "Something went wrong when updating tenant",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "apiKeyAuth": []
          },
          {
            "bearerAuth": []
          }
        ]
      },
      "post": {
        "tags": [
          "Company"
        ],
        "summary": "Create a KLARA business company",
        "description": "A Klara user might have multiple company tenants. Use this endpoint to create a business company and its correspondence tenant. Use your KLARA token from your username & password & tenant-id.",
        "requestBody": {
          "description": "The company information",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BusinessCompany"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Tenant and company created",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Tenant"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid company data",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Invalid credentials",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "The user has been disabled",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "API rate limit exceeded"
          },
          "500": {
            "description": "Something went wrong when creating tenant and business company",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "apiKeyAuth": []
          },
          {
            "bearerAuth": []
          }
        ]
      }
    },
    "/core/v2/tenants/individuals/profile": {
      "get": {
        "tags": [
          "Individual"
        ],
        "summary": "[PREVIEW_API] Get profile from tenant's ID",
        "responses": {
          "200": {
            "description": "Retrieved profile successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "participantId": {
                      "type": "string",
                      "readOnly": true,
                      "example": "969b2b24-5ffe-4b7c-b1e2-a2a59fb1acb5"
                    },
                    "firstName": {
                      "type": "string",
                      "example": "Nikola"
                    },
                    "lastName": {
                      "type": "string",
                      "example": "Tesla"
                    },
                    "email": {
                      "description": "Main email address",
                      "type": "string",
                      "example": "email@klara.ch"
                    },
                    "tenantEntryType": {
                      "description": "Tenant entry type of the profile",
                      "type": "string",
                      "example": "INDIVIDUAL"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Data invalid",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "401": {
            "description": "No Authorization header found or invalid token"
          },
          "404": {
            "description": "Profile not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "500": {
            "description": "Something went wrong on our side while processing the request. Please kindly contact our support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          }
        },
        "security": [
          {
            "apiKeyAuth": []
          },
          {
            "bearerAuth": []
          }
        ]
      },
      "post": {
        "tags": [
          "Individual"
        ],
        "summary": "[PREVIEW_API] Create profile",
        "responses": {
          "200": {
            "description": "Created profile successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "participantId": {
                      "type": "string",
                      "readOnly": true,
                      "example": "969b2b24-5ffe-4b7c-b1e2-a2a59fb1acb5"
                    },
                    "firstName": {
                      "type": "string",
                      "example": "Nikola"
                    },
                    "lastName": {
                      "type": "string",
                      "example": "Tesla"
                    },
                    "email": {
                      "description": "Main email address",
                      "type": "string",
                      "example": "email@klara.ch"
                    },
                    "tenantEntryType": {
                      "description": "Tenant entry type of the profile",
                      "type": "string",
                      "example": "INDIVIDUAL"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Data invalid",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "401": {
            "description": "No Authorization header found or invalid token"
          },
          "404": {
            "description": "Resource not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          },
          "500": {
            "description": "Something went wrong on our side while processing the request. Please kindly contact our support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorMessage"
                }
              }
            }
          }
        },
        "security": [
          {
            "apiKeyAuth": []
          },
          {
            "bearerAuth": []
          }
        ]
      }
    }
  },
  "components": {
    "schemas": {
      "AccessTokenResponse": {
        "type": "object",
        "properties": {
          "access_token": {
            "type": "string"
          },
          "expires_in": {
            "format": "int64",
            "type": "integer"
          },
          "refresh_expires_in": {
            "format": "int64",
            "type": "integer"
          },
          "refresh_token": {
            "type": "string"
          },
          "token_type": {
            "type": "string"
          },
          "id_token": {
            "type": "string"
          },
          "not-before-policy": {
            "format": "int32",
            "type": "integer"
          },
          "session_state": {
            "type": "string"
          },
          "otherClaims": {
            "type": "object",
            "additionalProperties": {
              "type": "object"
            }
          }
        }
      },
      "AddablePayslipSalaryItems": {
        "description": "The salary items that can be added to an employee's editable payslip, plus the resolved contract/payslip to chain into the add-salary-item call.",
        "type": "object",
        "properties": {
          "employeeId": {
            "format": "int64",
            "description": "Id of the employee the addable salary items were resolved for.",
            "type": "integer",
            "example": 3487
          },
          "contractId": {
            "format": "int64",
            "description": "Id of the employee's resolved main (latest) contract. Pass this to the add-salary-item call.",
            "type": "integer",
            "example": 9021
          },
          "payslipId": {
            "format": "int64",
            "description": "Id of the resolved editable payslip. Pass this to the add-salary-item call.",
            "type": "integer",
            "example": 9542
          },
          "periodFrom": {
            "format": "date-time",
            "description": "Month (first day) of the resolved payslip (yyyy-MM-ddT00:00:00Z).",
            "type": "string",
            "example": "2018-03-01T00:00:00Z"
          },
          "salaryItems": {
            "description": "Addable salary items as blank templates (value fields cleared), distinct by code.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AddableSalaryItem"
            }
          }
        }
      },
      "AddableSalaryItem": {
        "description": "A salary-item type that can be added to an employee's payslip (blank template, value fields cleared).",
        "type": "object",
        "properties": {
          "code": {
            "description": "Salary-type code. Send this as the salary item code when adding it to the payslip.",
            "type": "string",
            "example": "1005"
          },
          "name": {
            "description": "Canonical (non-localized) name of the salary item.",
            "type": "string",
            "example": "Hourly Salary"
          },
          "description": {
            "description": "Localised description/label of the salary item (localised via the Accept-Language header).",
            "type": "string",
            "example": "Stundenlohn"
          },
          "editableFields": {
            "description": "Comma-separated list of the value fields that can be provided when adding this salary item (baseValue, rate, quantity, value). The GUI implementation must base on this list to only show input box for fields that exist in this list.",
            "type": "string",
            "example": "baseValue,quantity"
          },
          "duplicatable": {
            "description": "Whether more than one instance of this salary item can be added to the same payslip. When false, only one instance of this salary item can be added, try to add another one will result in an error.",
            "type": "boolean",
            "example": true
          },
          "showOnPayslip": {
            "description": "Whether the salary item is shown on the payslip.",
            "type": "boolean",
            "example": true
          },
          "employerRelated": {
            "description": "Whether the salary item is employer-related (as opposed to employee-related).",
            "type": "boolean",
            "example": false
          },
          "paymentTypeSit": {
            "allOf": [
              {
                "$ref": "#/components/schemas/PaymentType"
              },
              {
                "description": "How the salary item is paid out. Allowed values: BANK, PAYINSLIP, CASH.",
                "example": "BANK"
              }
            ]
          },
          "salaryItemTypeId": {
            "format": "int64",
            "description": "Id of the underlying salary-item type definition.",
            "type": "integer",
            "example": 42
          },
          "accountingGroup": {
            "description": "Accounting group the salary item belongs to.",
            "type": "string",
            "example": "SALARY"
          },
          "printSequence": {
            "format": "int32",
            "description": "Print/order sequence of the salary item on the payslip.",
            "type": "integer",
            "example": 100
          }
        }
      },
      "Address": {
        "description": "An Address of a customer.",
        "required": [
          "addressLines",
          "addressType",
          "cityName",
          "countryIso2Code"
        ],
        "type": "object",
        "properties": {
          "id": {
            "description": "Id of this Address. Does not need to be included when creating customer",
            "type": "string",
            "example": "1"
          },
          "validFrom": {
            "format": "date",
            "description": "The timestamp from which this address is valid",
            "type": "string"
          },
          "validTo": {
            "format": "date",
            "description": "The timestamp to which this address is valid",
            "type": "string"
          },
          "addressLines": {
            "description": "The address lines for this Address",
            "type": "string",
            "example": "Chemin de la Caquerette 12"
          },
          "addressType": {
            "description": "The type of address, could be [PRIVATE, WORK, SHIPPING]. For company, address type <strong>MUST</strong> be <strong>PRIVATE</strong>. ",
            "pattern": "\\S",
            "type": "string",
            "example": "WORK",
            "nullable": false
          },
          "cityName": {
            "description": "Name of this City",
            "pattern": "\\S",
            "type": "string",
            "example": "Bern",
            "nullable": false
          },
          "cityZipCode": {
            "description": "The postal code of a city for this address",
            "type": "string",
            "example": "3003"
          },
          "countryIso2Code": {
            "description": "2 letter country code. For company, only accept Switzerland",
            "pattern": "\\S",
            "type": "string",
            "example": "CH",
            "nullable": false
          },
          "countryIso3Code": {
            "description": "3 letter country code. For company, only accept Switzerland",
            "type": "string",
            "example": "CHE"
          },
          "countryNumericCode": {
            "description": "ISO-numeric code. For company, only accept Switzerland",
            "type": "string",
            "example": "756"
          },
          "city_href": {
            "description": "The path to get City object by city's id, /cities/{}",
            "type": "string",
            "readOnly": true,
            "example": "https://api.klara.ch/core/latest/cities/1"
          },
          "definitionName": {
            "description": "definition name of this address; in case main address, value is null; else value is not blank",
            "type": "string",
            "example": "2nd address"
          },
          "additionalAddress": {
            "description": "Additional address for more specific",
            "type": "string",
            "example": "No. 13, street 123"
          }
        }
      },
      "ApplicabilityVatCaseType": {
        "enum": [
          "REVENUE",
          "COST"
        ],
        "type": "string"
      },
      "Article": {
        "description": "An article.",
        "required": [
          "nameDE",
          "unitDE",
          "accountingTags",
          "articleNumber",
          "productType"
        ],
        "type": "object",
        "properties": {
          "id": {
            "description": "Id of the article. Does not need to be included when creating article",
            "type": "string",
            "readOnly": true,
            "example": "1"
          },
          "nameDE": {
            "description": "Name of the article in German",
            "type": "string"
          },
          "nameEN": {
            "description": "Name of the article in English",
            "type": "string"
          },
          "nameFR": {
            "description": "Name of the article in French",
            "type": "string"
          },
          "nameIT": {
            "description": "Name of the article in Italian",
            "type": "string"
          },
          "descriptionDE": {
            "description": "Description of the article in German",
            "type": "string"
          },
          "descriptionEN": {
            "description": "Description of the article in English",
            "type": "string"
          },
          "descriptionFR": {
            "description": "Description of the article in French",
            "type": "string"
          },
          "descriptionIT": {
            "description": "Description of the article in Italian",
            "type": "string"
          },
          "extendedDescriptionDE": {
            "description": "Extended description of the article in German",
            "type": "string"
          },
          "extendedDescriptionEN": {
            "description": "Extended description of the article in English",
            "type": "string"
          },
          "extendedDescriptionFR": {
            "description": "Extended description of the article in French",
            "type": "string"
          },
          "extendedDescriptionIT": {
            "description": "Extended description of the article in Italian",
            "type": "string"
          },
          "unitDE": {
            "description": "Unit of the article in German",
            "type": "string"
          },
          "unitEN": {
            "description": "Unit of the article in English",
            "type": "string"
          },
          "unitFR": {
            "description": "Unit of the article in French",
            "type": "string"
          },
          "unitIT": {
            "description": "Unit of the article in Italian",
            "type": "string"
          },
          "barcode": {
            "description": "Barcode of the article",
            "type": "string"
          },
          "usePos": {
            "description": "Decides if this article is used for POS or not",
            "type": "boolean"
          },
          "pricePeriods": {
            "description": "Price periods for the article.<br /><a target=\"_blank\" href=\"/resources/articles/single-price-period.png\">If article only has single price period,</a> ignore and don't include validFrom and validTo in the PricePeriod.<br /><a target=\"_blank\" href=\"/resources/articles/multiple-price-periods.png\">If article have different prices valid for different periods</a>, set value for validFrom for each price period or that price period is ignored.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PricePeriod"
            }
          },
          "options": {
            "description": "Options for the article. If specify, variants for this article will be generated.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ArticleOption"
            }
          },
          "imageHrefs": {
            "description": "Reference uris for the images of this article if present.",
            "type": "array",
            "items": {
              "type": "string"
            },
            "readOnly": true,
            "example": [
              "https://api.klara.ch/core/latest/articles/1/images/1"
            ]
          },
          "isArticleSet": {
            "description": "Decides if this article is an article set",
            "type": "boolean"
          },
          "articleSetName": {
            "description": "Name of the article set. Does not need to be included if article is not an article set.",
            "type": "string"
          },
          "defaultQuantity": {
            "description": "The default quantity of the article",
            "pattern": "^\\d{1,19}([.]\\d{1,2})?$",
            "type": "number"
          },
          "accountingTags": {
            "description": "Tags used for accounting. Articles with the same tag, same VAT case and same VAT rate are grouped together in the posting",
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "articleNumber": {
            "description": "Article number",
            "type": "string",
            "example": "ABC123"
          },
          "hasVariant": {
            "description": "Specify if the article has variants or not",
            "type": "boolean"
          },
          "includedInArticleSets": {
            "description": "Names of the article sets that the article is included in.<br />If the article have some variants, then only the variants will show the article set name they belong to, not the parent article (null value is shown).",
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "sellInOnlineShop": {
            "description": "Specify if the article is able to be sold on the Online shop or not",
            "type": "boolean"
          },
          "isAdultArticle": {
            "description": "Specify if the article is only used for adult or not",
            "type": "boolean"
          },
          "productType": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ProductType"
              },
              {
                "description": "The product type of the article"
              }
            ]
          },
          "posCategories": {
            "description": "Categories used for Point of Sale of the article<br />Provide only either id or href of each category when creating Article",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ArticleCategoryRef"
            }
          },
          "posFilters": {
            "description": "Filters used for Point of Sale of the article<br />Provide only either id or href of each filter when creating Article",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ArticleFilterRef"
            }
          },
          "onlineShopCategories": {
            "description": "Categories used for Online shop of the article<br />Provide only either id or href of each category when creating Article",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ArticleCategoryRef"
            }
          },
          "onlineShopFilters": {
            "description": "Filters used for Online shop of the article<br />Provide only either id or href of each filter when creating Article",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ArticleFilterRef"
            }
          },
          "bookingCategories": {
            "description": "Categories used for Online Booking of the article<br /> Provide only either id or href of each category when creating Article",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ArticleCategoryRef"
            }
          },
          "searchTags": {
            "description": "Search tags make it easier for your customer to find your product in the online shop",
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "shippingInfo": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ShippingInfo"
              },
              {
                "description": "Information used for shipping in the Online Shop"
              }
            ]
          },
          "_links": {
            "allOf": [
              {
                "$ref": "#/components/schemas/RepresentationLinks"
              },
              {
                "readOnly": true
              }
            ]
          },
          "vats": {
            "description": "VAT information for the article",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ArticleVat"
            }
          },
          "numberType": {
            "allOf": [
              {
                "$ref": "#/components/schemas/InventoryNumberType"
              },
              {
                "description": "Inventory Number Type<br />Use either NO_NUMBER or SERIAL_NUMBER"
              }
            ]
          }
        }
      },
      "ArticleAndVariant": {
        "description": "Article and variant.",
        "type": "object",
        "properties": {
          "id": {
            "description": "Id of the article",
            "type": "string",
            "example": "1"
          },
          "name": {
            "description": "Name of the article",
            "type": "string"
          },
          "description": {
            "description": "Description for the article",
            "type": "string"
          },
          "extendedDescription": {
            "description": "This description will be used for example in your online shop",
            "type": "string"
          },
          "unit": {
            "description": "Define how the article is count by",
            "type": "string"
          },
          "barcode": {
            "description": "Barcode of the article",
            "type": "string"
          },
          "defaultQuantity": {
            "description": "The default quantity of the article",
            "type": "number"
          },
          "accountingTags": {
            "description": "Tags used for accounting. Articles with the same tag, same VAT case and same VAT rate are grouped together in the posting",
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "articleNumber": {
            "description": "Number of the article",
            "type": "string",
            "example": "ABC123"
          },
          "productType": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ProductType"
              },
              {
                "description": "The product type of the article"
              }
            ]
          },
          "priceCategories": {
            "description": "Price categories of the article",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ArticlePriceCategory"
            }
          },
          "vatRate": {
            "description": "Vat rate of the article",
            "type": "number"
          },
          "articleType": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ArticleType"
              },
              {
                "description": "Article type"
              }
            ]
          },
          "priceIncludeVat": {
            "description": "price include vat",
            "type": "number"
          },
          "priceExcludeVat": {
            "description": "price exclude vat",
            "type": "number"
          },
          "hasInventory": {
            "description": "This article has inventory or not",
            "type": "boolean"
          },
          "quantityInStock": {
            "description": "Quantity in stock",
            "type": "number"
          },
          "optionValues": {
            "description": "Variant option of this article",
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "ableToOrderOutOfStock": {
            "description": "Flag define the article is allow to order out of stock",
            "type": "boolean"
          }
        }
      },
      "ArticleCategory": {
        "description": "A Category used for an Article.",
        "required": [
          "nameDE"
        ],
        "type": "object",
        "properties": {
          "id": {
            "description": "Id of the category. Does not need to be included when creating article category",
            "type": "string",
            "readOnly": true,
            "example": "1"
          },
          "nameDE": {
            "description": "Name of the category in German",
            "type": "string",
            "example": "German name"
          },
          "nameEN": {
            "description": "Name of the category in English",
            "type": "string",
            "example": "English name"
          },
          "nameFR": {
            "description": "Name of the category in French",
            "type": "string",
            "example": "French name"
          },
          "nameIT": {
            "description": "Name of the category in Italian",
            "type": "string",
            "example": "Italian name"
          },
          "order": {
            "format": "int32",
            "description": "Order of this category.<br />Does not need to be included when creating article category.",
            "type": "integer",
            "readOnly": true
          },
          "active": {
            "description": "Indicates if the category is active or not",
            "type": "boolean"
          },
          "imageId": {
            "description": "Image Id of the category. Does not need to be included when creating article category",
            "type": "string",
            "readOnly": true,
            "example": "1"
          },
          "_links": {
            "allOf": [
              {
                "$ref": "#/components/schemas/RepresentationLinks"
              },
              {
                "readOnly": true
              }
            ]
          }
        }
      },
      "ArticleCategoryRef": {
        "description": "A reference to an ArticleCategory",
        "required": [
          "category_href"
        ],
        "type": "object",
        "properties": {
          "id": {
            "description": "Id of the category. Does not need to be included when creating article",
            "type": "string",
            "readOnly": true,
            "example": "1"
          },
          "category_href": {
            "description": "Reference uri for an article category. If specified, this article will be assigned to the entered article category.",
            "type": "string",
            "example": "https://api.klara.ch/core/latest/article-categories/1",
            "writeOnly": true
          },
          "nameDE": {
            "description": "Name of the category in german. <br />Does not need to be included when creating article.",
            "type": "string",
            "readOnly": true,
            "example": "shop"
          },
          "nameEN": {
            "description": "Name of the category in english. <br />Does not need to be included when creating article.",
            "type": "string",
            "readOnly": true,
            "example": "shop"
          },
          "nameFR": {
            "description": "Name of the category in french. <br />Does not need to be included when creating article.",
            "type": "string",
            "readOnly": true,
            "example": "shop"
          },
          "nameIT": {
            "description": "Name of the category in italy. <br />Does not need to be included when creating article.",
            "type": "string",
            "readOnly": true,
            "example": "shop"
          },
          "order": {
            "format": "int32",
            "description": "Order of this category. <br />Does not need to be included when creating article.",
            "type": "integer",
            "readOnly": true
          },
          "active": {
            "description": "Indicates if the category is active or not",
            "type": "boolean",
            "readOnly": true
          },
          "_links": {
            "allOf": [
              {
                "$ref": "#/components/schemas/RepresentationLinks"
              },
              {
                "readOnly": true
              }
            ]
          }
        }
      },
      "ArticleFilter": {
        "description": "A Filter used for an Article.",
        "required": [
          "nameDE"
        ],
        "type": "object",
        "properties": {
          "id": {
            "description": "Id of the filter. Does not need to be included when creating article filter",
            "type": "string",
            "readOnly": true,
            "example": "1"
          },
          "nameDE": {
            "description": "Name of the filter in german",
            "type": "string",
            "example": "shop"
          },
          "nameEN": {
            "description": "Name of the filter in english",
            "type": "string",
            "example": "shop"
          },
          "nameFR": {
            "description": "Name of the filter in french",
            "type": "string",
            "example": "shop"
          },
          "nameIT": {
            "description": "Name of the filter in italy",
            "type": "string",
            "example": "shop"
          },
          "order": {
            "format": "int32",
            "description": "Order of this filter. <br />Does not need to be included when creating article filter.",
            "type": "integer"
          },
          "active": {
            "description": "Indicates if the filter is active or not",
            "type": "boolean"
          },
          "imageId": {
            "description": "The image id of the filter. Does not need to be included when creating article",
            "type": "string",
            "readOnly": true
          },
          "_links": {
            "allOf": [
              {
                "$ref": "#/components/schemas/RepresentationLinks"
              },
              {
                "readOnly": true
              }
            ]
          }
        }
      },
      "ArticleFilterRef": {
        "description": "A reference to an ArticleFilter",
        "required": [
          "filter_href"
        ],
        "type": "object",
        "properties": {
          "id": {
            "description": "Id of the filter. Does not need to be included when creating article.",
            "type": "string",
            "readOnly": true,
            "example": "1"
          },
          "filter_href": {
            "description": "Reference uri for an article filter. If specified, this article will be assigned to the entered article filter.",
            "type": "string",
            "example": "https://api.klara.ch/core/latest/article-filters/1",
            "writeOnly": true
          },
          "nameDE": {
            "description": "Name of the filter in german. <br />Does not need to be included when creating article.",
            "type": "string",
            "readOnly": true,
            "example": "shop"
          },
          "nameEN": {
            "description": "Name of the filter in english. <br />Does not need to be included when creating article.",
            "type": "string",
            "readOnly": true,
            "example": "shop"
          },
          "nameFR": {
            "description": "Name of the filter in french. <br />Does not need to be included when creating article.",
            "type": "string",
            "readOnly": true,
            "example": "shop"
          },
          "nameIT": {
            "description": "Name of the filter in italy. <br />Does not need to be included when creating article.",
            "type": "string",
            "readOnly": true,
            "example": "shop"
          },
          "order": {
            "format": "int32",
            "description": "Order of this filter. <br />Does not need to be included when creating article.",
            "type": "integer",
            "readOnly": true
          },
          "active": {
            "description": "Indicates if the filter is active or not",
            "type": "boolean",
            "readOnly": true
          },
          "_links": {
            "allOf": [
              {
                "$ref": "#/components/schemas/RepresentationLinks"
              },
              {
                "readOnly": true
              }
            ]
          }
        }
      },
      "ArticleImage": {
        "description": "An article image.",
        "type": "object",
        "properties": {
          "imageId": {
            "type": "string"
          }
        }
      },
      "ArticleOption": {
        "description": "An option for an article.",
        "type": "object",
        "properties": {
          "name": {
            "description": "Name of the article option",
            "type": "string",
            "example": "color"
          },
          "values": {
            "description": "Available choices for the article option",
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        }
      },
      "ArticlePriceCategory": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string"
          },
          "priceIncludeVat": {
            "type": "number"
          },
          "priceExcludeVat": {
            "type": "number"
          }
        }
      },
      "ArticleType": {
        "enum": [
          "ARTICLE",
          "ARTICLE_SET",
          "VARIANT"
        ],
        "type": "string"
      },
      "ArticleVat": {
        "type": "object",
        "properties": {
          "vatType": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ArticleVatType"
              },
              {
                "description": "Article vat type of the article",
                "example": "NORMAL"
              }
            ]
          },
          "vatCase": {
            "description": "VAT case of the article",
            "type": "string",
            "example": "TAXABLE_SUPPLY"
          },
          "vatCode": {
            "description": "VAT code of the article VAT",
            "type": "string",
            "example": "1"
          },
          "sss1": {
            "description": "Reporting net tax rate with SSS1 option",
            "type": "boolean",
            "example": false
          },
          "sss2": {
            "description": "Reporting net tax rate with SSS2 option",
            "type": "boolean",
            "example": false
          },
          "reportingNetTaxRate": {
            "description": "Using VAT reporting net tax rate option",
            "type": "boolean",
            "example": false
          },
          "excludeVat": {
            "description": "Using exclude VAT option",
            "type": "boolean",
            "example": false
          }
        }
      },
      "ArticleVatType": {
        "enum": [
          "NORMAL",
          "ABROAD",
          "TAKE_AWAY"
        ],
        "type": "string"
      },
      "BinaryFile": {
        "description": "A binary file, users can push the binary via API document for testing.",
        "type": "object",
        "properties": {
          "file": {
            "format": "binary",
            "type": "string"
          }
        }
      },
      "BulkArticleCreatingResponse": {
        "description": "A response when creating a list of articles",
        "type": "object",
        "properties": {
          "numberOfSuccess": {
            "format": "int32",
            "description": "Number of articles saved successfully",
            "type": "integer",
            "example": 2
          },
          "numberOfFail": {
            "format": "int32",
            "description": "Number of articles saved unsuccessfully",
            "type": "integer",
            "example": 2
          },
          "success": {
            "description": "A list of saved articles",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Article"
            }
          },
          "fail": {
            "description": "A list of unsaved articles with error message",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PublicApiFailArticle"
            }
          }
        }
      },
      "BusinessCompany": {
        "description": "A business company.",
        "required": [
          "name",
          "legalForm",
          "phones",
          "emails",
          "addresses",
          "language"
        ],
        "type": "object",
        "properties": {
          "name": {
            "description": "Name of the company",
            "pattern": "\\S",
            "type": "string",
            "example": "ABC-Corp",
            "nullable": false
          },
          "legalForm": {
            "allOf": [
              {
                "$ref": "#/components/schemas/LegalForm"
              },
              {
                "description": "Legal form of a company. Can be one of the following: <ul><li>Limited liability company(GmbH)</li><li>Public limited company (AG)</li><li>Individually owned company (EU)</li><li>Association (V)</li><li>Simple partnership (EG)</li><li>General partnership (KG)</li><li>Limited partnership (KDG)</li><li>Cooperative company (G)</li><li>Foundation (S)</li><li>OR</li></ul>",
                "enum": [
                  "GmbH",
                  "AG",
                  "OR",
                  "EU",
                  "V",
                  "EG",
                  "KG",
                  "KDG",
                  "G",
                  "S"
                ],
                "example": "LIMITED_LIABILITY",
                "nullable": false
              }
            ]
          },
          "phones": {
            "description": "Phone numbers of the company",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Phone"
            },
            "nullable": false
          },
          "emails": {
            "description": "Emails of this company",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Email"
            },
            "nullable": false
          },
          "addresses": {
            "description": "Address list of this company, at least one should be add. For company, address type <strong>MUST</strong> be <strong>PRIVATE</strong>",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Address"
            },
            "nullable": false
          },
          "language": {
            "description": "Preferred language of the company. Supported: English, German, French, Italian",
            "pattern": "\\S",
            "enum": [
              "de",
              "en",
              "fr",
              "it"
            ],
            "type": "string",
            "example": "de",
            "nullable": false
          },
          "corporateIdentificationNumber": {
            "description": "Every business active in Switzerland is given a unique enterprise identification number (UID). To ensure that numbers are correctly allocated and managed, the UID register is run by the Federal Statistical Office",
            "type": "string",
            "example": "CHE-123.456.789"
          },
          "foundingDate": {
            "format": "date",
            "description": "Founding date of this company in ISO 8601 format (yyyy-mm-dd)",
            "type": "string",
            "example": "2019-12-20"
          }
        }
      },
      "CategoryAssigningGroup": {
        "description": "A list of article ids need to be assigned the category",
        "type": "object",
        "properties": {
          "articleIdsForOnlineShop": {
            "description": "Article ids need to be assigned with a online shop category",
            "uniqueItems": true,
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "articleIdsForBooking": {
            "description": "Article ids need to be assigned with a booking category",
            "uniqueItems": true,
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "articleIdsForPos": {
            "description": "Article ids need to be assigned with a pos category",
            "uniqueItems": true,
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        }
      },
      "City": {
        "description": "A City that this partner locates.",
        "type": "object",
        "properties": {
          "id": {
            "format": "int64",
            "description": "The id of this City object",
            "type": "integer",
            "readOnly": true,
            "example": 1
          },
          "zipCode": {
            "description": "The postal code for this city",
            "type": "string",
            "example": "8034"
          },
          "basicPostcode": {
            "type": "string"
          },
          "name": {
            "description": "Name of this City",
            "type": "string",
            "example": "Gerlafingen"
          },
          "cityName27": {
            "type": "string"
          },
          "state": {
            "allOf": [
              {
                "$ref": "#/components/schemas/State"
              },
              {
                "description": "The State for this City"
              }
            ]
          },
          "community": {
            "allOf": [
              {
                "$ref": "#/components/schemas/Community"
              },
              {
                "description": "The Community for this City"
              }
            ]
          },
          "country": {
            "allOf": [
              {
                "$ref": "#/components/schemas/Country"
              },
              {
                "description": "The Country of this City"
              }
            ]
          }
        }
      },
      "Community": {
        "description": "A Community that this partner locates.",
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "readOnly": true
          },
          "bfsNumber": {
            "format": "int32",
            "description": "BFS number of this Community",
            "type": "integer",
            "example": 5480
          },
          "communityName": {
            "description": "Name of this Community",
            "type": "string",
            "example": "Daillens"
          },
          "conurbationNumber": {
            "description": "Conurbation number of this Community",
            "type": "string",
            "example": "5586"
          },
          "state": {
            "allOf": [
              {
                "$ref": "#/components/schemas/State"
              },
              {
                "description": "State of this community"
              }
            ]
          }
        }
      },
      "Company": {
        "description": "A company.",
        "required": [
          "correspondence",
          "name"
        ],
        "type": "object",
        "properties": {
          "website": {
            "description": "The website address of this customer",
            "type": "string",
            "example": "www.my-company.com"
          },
          "categories": {
            "description": "Add one or more categories to this customer that you can use as filter criteria for selecting partners",
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "onlinePlatforms": {
            "description": "The list of online platforms that this customer uses",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/OnlinePlatform"
            }
          },
          "language": {
            "description": "The main language that this partner uses, valid values is [en, de, fr, it]",
            "type": "string",
            "example": "en"
          },
          "responsibleCounterpart": {
            "description": "The name of a contact person for this customer",
            "type": "string",
            "example": "Mr. Marc"
          },
          "correspondence": {
            "allOf": [
              {
                "$ref": "#/components/schemas/Correspondence"
              },
              {
                "description": "The preferred method of correspondence, how this customer wants to receive the pay slips by default",
                "example": "MAIL",
                "nullable": false
              }
            ]
          },
          "id": {
            "description": "Id of this company. Does not need to be included when creating customer",
            "type": "string",
            "readOnly": true,
            "example": "1"
          },
          "name": {
            "description": "Name of the company",
            "pattern": "\\S",
            "type": "string",
            "example": "ABC-Corp",
            "nullable": false
          },
          "phones": {
            "description": "Phone numbers of the company",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Phone"
            }
          },
          "emails": {
            "description": "Emails of this company",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Email"
            }
          },
          "addresses": {
            "description": "Address list of this company, atleast one should be add",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Address"
            }
          },
          "corporateIdentificationNumber": {
            "description": "Every business active in Switzerland is given a unique enterprise identification number (UID). To ensure that numbers are correctly allocated and managed, the UID register is run by the Federal Statistical Office",
            "type": "string",
            "example": "CHE-123.456.789"
          },
          "vatNumber": {
            "description": "This is the official CH VAT number of the company",
            "type": "string",
            "example": "CHE-123.456.789"
          },
          "hrNumber": {
            "description": "This is the official CH number for this company in the CH trade register",
            "type": "string",
            "example": "CHE-123.456.789"
          },
          "nogaCode": {
            "description": "The NOGA code of this company",
            "type": "string",
            "example": "1234"
          },
          "foundingDate": {
            "format": "date",
            "description": "Founding date of this comany in ISO 8601 format (yyyy-mm-dd)",
            "type": "string",
            "example": "2019-12-20"
          },
          "companyNumber": {
            "description": "This is a number the KLARA user can give to this customer/partner/supplier",
            "type": "string"
          }
        }
      },
      "CompanyBankAccount": {
        "type": "object",
        "properties": {
          "id": {
            "format": "int64",
            "description": "Internal database id of the bank account.",
            "type": "integer",
            "example": 1
          },
          "companyId": {
            "format": "int64",
            "description": "KLARA company id this bank account belongs to.",
            "type": "integer",
            "example": 1
          },
          "shortName": {
            "description": "User-defined short label for the bank account.",
            "type": "string",
            "example": "PostFinance CHF"
          },
          "ibanNumber": {
            "description": "IBAN in pretty-printed form (groups of 4 characters).",
            "type": "string",
            "example": "CH71 0900 0000 2529 4693 2"
          },
          "qrIbanNumber": {
            "description": "QR-IBAN (only set when markedQrIban is true).",
            "type": "string",
            "example": "CH44 3199 9123 0008 8901 2"
          },
          "currency": {
            "description": "ISO-style currency code. Allowed values: CHF, CHW.",
            "type": "string",
            "example": "CHF"
          },
          "wirAcceptanceRate": {
            "description": "WIR acceptance percentage (0–100).",
            "type": "number",
            "example": 0
          },
          "markedHRPayment": {
            "description": "Default account for salary / HR payments.",
            "type": "boolean",
            "example": false
          },
          "markedARAccount": {
            "description": "Default account for Accounts Receivable.",
            "type": "boolean",
            "example": true
          },
          "markedAPAccount": {
            "description": "Default account for Accounts Payable.",
            "type": "boolean",
            "example": false
          },
          "markedPaymentSlip": {
            "description": "ESR / red payment-slip enabled.",
            "type": "boolean",
            "example": false
          },
          "markedQrInvoice": {
            "description": "QR-invoice payment enabled.",
            "type": "boolean",
            "example": true
          },
          "markedQrIban": {
            "description": "QR-IBAN flow enabled.",
            "type": "boolean",
            "example": false
          },
          "participantNumber": {
            "description": "ESR participant number (only when markedPaymentSlip).",
            "type": "string",
            "example": "01-12345-6"
          },
          "customerIdentificationNumber": {
            "description": "ESR customer identification number (only when markedPaymentSlip and not PostFinance).",
            "type": "string",
            "example": "123456"
          },
          "printParticipantNumber": {
            "description": "Print the participant number on payment slips.",
            "type": "boolean",
            "example": false
          },
          "printBankAddress": {
            "description": "Print the bank address on payment slips.",
            "type": "boolean",
            "example": false
          },
          "printBeneficiary": {
            "description": "Print the beneficiary on payment slips.",
            "type": "boolean",
            "example": false
          },
          "esrPrintingType": {
            "description": "ESR printing type. Allowed values: INTEGRATE, SEPARATE.",
            "type": "string",
            "example": "INTEGRATE"
          },
          "contractNumber": {
            "description": "Bank contract number.",
            "type": "string",
            "example": ""
          },
          "batchBooking": {
            "description": "Batch-booking preference. Allowed values: DEFAULT, ACTIVE, INACTIVE.",
            "type": "string",
            "example": "DEFAULT"
          },
          "debitAdvice": {
            "description": "Debit-advice preference. Allowed values: DEFAULT, NO_ADVICE, SINGLE_ADVICE, ADVICE_WITHOUT_DETAILS, ADVICE_WITH_DETAIL.",
            "type": "string",
            "example": "DEFAULT"
          },
          "notMarkedSalaryPayments": {
            "description": "When true, exclude this bank account from salary-payment runs.",
            "type": "boolean",
            "example": false
          },
          "swissBank": {
            "allOf": [
              {
                "$ref": "#/components/schemas/SwissBank"
              },
              {
                "description": "Resolved Swiss-bank master-data record (name, address, BCNR). May have empty fields when the IBAN's clearing number does not match a known Swiss bank."
              }
            ]
          }
        }
      },
      "CompanyConfigurationIncludingVatResult": {
        "type": "object",
        "properties": {
          "includingVat": {
            "description": "Whether invoice amounts for the authenticated company are displayed and calculated including VAT. When <code>true</code>, VAT is baked into the displayed prices. When <code>false</code>, VAT is shown as a separate line item. Returns <code>false</code> when no configuration record has been set for the company.",
            "type": "boolean",
            "example": false
          }
        }
      },
      "CompanyDocumentUploadForm": {
        "description": "Multipart form body: a document category and a single file (max 25 MB).",
        "required": [
          "category",
          "file"
        ],
        "type": "object",
        "properties": {
          "category": {
            "description": "Document category. Determines where the file is stored and which downstream post-processing is triggered (e.g. LIABILITY_UPLOAD triggers asynchronous AI analysis). <strong>Important:</strong> For the <strong>create booking</strong> functionality, only <code>LIABILITY_UPLOAD</code> is allowed — the booking creation GUI must always use <code>LIABILITY_UPLOAD</code> when uploading documents in this context.",
            "enum": [
              "SALARY_STATEMENTS",
              "YEARLY_REPORTS",
              "PAYMENT_FILES",
              "INSURANCE_CERTIFICATES",
              "SALARY_TRANSMISSIONS",
              "OWN_DOCUMENTS",
              "LIABILITY_UPLOAD",
              "EXPENSES",
              "LIABILITIES"
            ],
            "type": "string"
          },
          "file": {
            "format": "binary",
            "description": "The document file to upload. Maximum size 25 MB. Allowed file types are enforced by the downstream service.",
            "type": "string"
          }
        }
      },
      "CompanyVAT": {
        "description": "A Company VAT.",
        "type": "object",
        "properties": {
          "id": {
            "description": "Id of the company VAT.",
            "type": "string",
            "example": "123"
          },
          "hasVat": {
            "description": "Flag mark the company have VAT or not.",
            "type": "boolean"
          },
          "vatNumber": {
            "description": "The VAT number.",
            "type": "string",
            "example": "ABC-123"
          },
          "validFrom": {
            "format": "date",
            "description": "The company VAT is valid from this time.",
            "type": "string"
          },
          "validTo": {
            "format": "date",
            "description": "The company VAT is invalid after this time.",
            "type": "string"
          },
          "companyId": {
            "format": "int64",
            "description": "Id of the company",
            "type": "integer",
            "example": 1
          },
          "vats": {
            "description": "This is list VAT value of the company.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/VAT"
            }
          }
        }
      },
      "Correspondence": {
        "enum": [
          "MAIL",
          "EMAIL"
        ],
        "type": "string"
      },
      "Country": {
        "description": "A Country that this partner locates.",
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "readOnly": true
          },
          "countryName": {
            "description": "Name of this Country",
            "type": "string",
            "example": "Schweiz"
          },
          "iso2Code": {
            "description": "2 letter country code",
            "type": "string",
            "example": "CH"
          },
          "iso3Code": {
            "description": "3 letter country code",
            "type": "string",
            "example": "CHE"
          },
          "phoneCode": {
            "description": "Country calling code",
            "type": "string",
            "example": 41
          },
          "numericCode": {
            "description": "ISO-numeric code",
            "type": "string",
            "example": "756"
          }
        }
      },
      "CustomField": {
        "description": "A custom field.",
        "type": "object",
        "properties": {
          "id": {
            "description": "Id of this custom field. Does not need to be included when creating CustomerContact",
            "type": "string",
            "readOnly": true,
            "example": "1"
          },
          "customName": {
            "description": "name of this custom field",
            "type": "string",
            "example": "name at home"
          },
          "customValue": {
            "description": "value of this custom field",
            "type": "string",
            "example": "John Henry"
          }
        }
      },
      "Customer": {
        "description": "A customer.",
        "required": [
          "customerType"
        ],
        "type": "object",
        "properties": {
          "id": {
            "description": "Id of this Customer. Does not need to be included when creating customer",
            "type": "string",
            "readOnly": true,
            "example": "1"
          },
          "person": {
            "allOf": [
              {
                "$ref": "#/components/schemas/Person"
              },
              {
                "description": "The Person object for when the customer type is Person."
              }
            ]
          },
          "company": {
            "allOf": [
              {
                "$ref": "#/components/schemas/Company"
              },
              {
                "description": "The Company object for when the customer type is Person."
              }
            ]
          },
          "priceCategory": {
            "description": "You can select / enter a price category. On the articles you can define a special price for this price category. When such an article is sold / invoiced, the price of this category will apply if it is identical for the article and the customer.",
            "type": "string",
            "example": "Sale price"
          },
          "customerType": {
            "allOf": [
              {
                "$ref": "#/components/schemas/CustomerType"
              },
              {
                "description": "The type of this partner. Could be either Person or Company.",
                "example": "PERSON",
                "nullable": false
              }
            ]
          },
          "_links": {
            "allOf": [
              {
                "$ref": "#/components/schemas/RepresentationLinks"
              },
              {
                "readOnly": true
              }
            ]
          }
        }
      },
      "CustomerContact": {
        "description": "A customer's contact.",
        "required": [
          "firstName",
          "lastName"
        ],
        "type": "object",
        "properties": {
          "id": {
            "description": "Id of this contact. Does not need to be included when creating CustomerContact",
            "type": "string",
            "readOnly": true,
            "example": "1"
          },
          "imageId": {
            "description": "Id of this contact's image. Does not need to be included when creating CustomerContact",
            "type": "string",
            "readOnly": true,
            "example": "1"
          },
          "salutation": {
            "allOf": [
              {
                "$ref": "#/components/schemas/Salutation"
              },
              {
                "description": "Salutation for this contact",
                "example": "MALE"
              }
            ]
          },
          "firstName": {
            "description": "First name of this contact",
            "type": "string",
            "example": "John"
          },
          "lastName": {
            "description": "Last name of this contact",
            "type": "string",
            "example": "Henry"
          },
          "email": {
            "description": "Email of this contact",
            "type": "string",
            "example": "john.henry@gmail.com"
          },
          "website": {
            "description": "Website of this contact",
            "type": "string",
            "example": "www.youtube.com"
          },
          "additionalAddressDefinition": {
            "description": "Additional address definition of this contact",
            "type": "string"
          },
          "phones": {
            "description": "Phone number list of this contact",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Phone"
            }
          },
          "categories": {
            "description": "Category list of this contact",
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "onlinePlatforms": {
            "description": "The list of online platforms that this contact uses",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/OnlinePlatform"
            }
          },
          "customFields": {
            "description": "The list of custom information of this contact",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CustomField"
            }
          },
          "function": {
            "description": "Function of this contact",
            "type": "string"
          },
          "birthday": {
            "format": "date",
            "description": "Birth date of this person in ISO 8601 format (yyyy-mm-dd)",
            "type": "string",
            "example": "2020-12-20"
          },
          "note": {
            "description": "Note of this contact",
            "type": "string",
            "example": "this is a important contact."
          }
        }
      },
      "CustomerType": {
        "enum": [
          "COMPANY",
          "PERSON"
        ],
        "type": "string"
      },
      "DimensionUnit": {
        "description": "Dimension unit used for shipping of the article",
        "enum": [
          "CENTIMETER",
          "METER"
        ],
        "type": "string"
      },
      "Email": {
        "description": "An Email address.",
        "required": [
          "type"
        ],
        "type": "object",
        "properties": {
          "id": {
            "description": "Id of this Email. <strong>Does not need to be included</strong> when creating customer",
            "type": "string",
            "example": "1"
          },
          "emailAddress": {
            "description": "Email address",
            "type": "string",
            "example": "example@gmail.com"
          },
          "type": {
            "allOf": [
              {
                "$ref": "#/components/schemas/EmailType"
              },
              {
                "description": "Type of this email",
                "enum": [
                  "PRIVATE",
                  "WORK",
                  "OFFICE"
                ],
                "example": "PRIVATE",
                "nullable": false
              }
            ]
          }
        }
      },
      "EmailType": {
        "enum": [
          "PRIVATE",
          "WORK",
          "OFFICE",
          "OTHER"
        ],
        "type": "string"
      },
      "ErrorMessage": {
        "type": "object",
        "properties": {
          "uuid": {
            "type": "string"
          },
          "createdTime": {
            "type": "string"
          },
          "code": {
            "type": "string"
          },
          "message": {
            "type": "string"
          },
          "detail": {
            "type": "string",
            "deprecated": true
          }
        }
      },
      "ErrorMessage1": {
        "type": "object",
        "properties": {
          "uuid": {
            "type": "string"
          },
          "createdTime": {
            "type": "string"
          },
          "code": {
            "type": "string"
          },
          "message": {
            "type": "string"
          },
          "detail": {
            "type": "string"
          }
        }
      },
      "ErrorResponse": {
        "type": "object",
        "properties": {
          "error": {
            "description": "Summary of the error response",
            "type": "string"
          },
          "error_description": {
            "description": "Description of the error response",
            "type": "string"
          }
        }
      },
      "FileType": {
        "enum": [
          "JSON",
          "CSV"
        ],
        "type": "string"
      },
      "FilterAssigningGroup": {
        "description": "A bunch of article ids need to be assigned the filter",
        "type": "object",
        "properties": {
          "assignedPosArticleIds": {
            "description": "Article ids will have the filter as a pos filter",
            "uniqueItems": true,
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "assignedOnlineShopArticleIds": {
            "description": "Article ids will have the filter as a online shop filter",
            "uniqueItems": true,
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "assignedBookingArticleIds": {
            "description": "Article ids will have the filter as a booking filter",
            "uniqueItems": true,
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        }
      },
      "InventoryNumberType": {
        "enum": [
          "NO_NUMBER",
          "BATCH_NUMBER",
          "SERIAL_NUMBER"
        ],
        "type": "string"
      },
      "Invoice": {
        "description": "An invoice document (creation or update). The polymorphic discriminator <code>orderType</code> is always <code>INVOICE</code>. Server-managed read-only fields (<code>vatDate</code>, <code>lastModified</code>, <code>createDate</code>, <code>bookingDueDate</code>, <code>bookingNumbers</code>, <code>businessCaseId</code>) are populated on the response.",
        "required": [
          "invoiceCode"
        ],
        "type": "object",
        "properties": {
          "id": {
            "format": "int64",
            "description": "Invoice id. Must be <code>0</code> or omitted when creating a new invoice. This endpoint only supports creation; updating an existing invoice is not supported.",
            "type": "integer",
            "example": 0
          },
          "orderType": {
            "description": "Polymorphic discriminator. Must be <code>INVOICE</code>. Allowed values: <code>INVOICE</code>.",
            "default": "INVOICE",
            "type": "string",
            "example": "INVOICE"
          },
          "status": {
            "description": "Invoice status. Allowed values: <code>DRAFT</code>, <code>INVOICED</code>, <code>SENT</code>, <code>PAID</code>, <code>CANCELLED</code>. Required. Status <code>INVOICED</code> or <code>SENT</code> triggers accounting booking.",
            "type": "string",
            "example": "INVOICED"
          },
          "invoiceCode": {
            "description": "Human-readable invoice code. Required and unique per company.",
            "maxLength": 64,
            "pattern": "\\S",
            "type": "string",
            "example": "INV-2026-001",
            "nullable": false
          },
          "invoiceNumber": {
            "format": "int64",
            "description": "Sequential invoice number, typically obtained from <code>GET /invoices/next-invoice-number</code>.",
            "type": "integer",
            "example": 2026001
          },
          "documentDate": {
            "format": "date",
            "description": "Invoice document date (ISO 8601). Required when <code>amount</code> is greater than 0. Must fall inside the company's active Order Management subscription period.",
            "type": "string",
            "example": "2026-05-28"
          },
          "paymentDate": {
            "format": "date",
            "description": "Payment due date (ISO 8601). Required when <code>amount</code> is greater than 0. Must be on or after <code>documentDate</code>.",
            "type": "string",
            "example": "2026-06-27"
          },
          "deliveryDate": {
            "format": "date",
            "description": "Service delivery date (ISO 8601).",
            "type": "string",
            "example": "2026-05-25"
          },
          "issuedDate": {
            "format": "date",
            "description": "Date the invoice was issued (ISO 8601).",
            "type": "string",
            "example": "2026-05-28"
          },
          "servicePeriodFrom": {
            "format": "date",
            "description": "Service period start date (ISO 8601).",
            "type": "string",
            "example": "2026-05-01"
          },
          "servicePeriodTo": {
            "format": "date",
            "description": "Service period end date (ISO 8601).",
            "type": "string",
            "example": "2026-05-31"
          },
          "servicePeriodPattern": {
            "description": "Service period pattern label (e.g. <code>MONTHLY</code>, <code>YEARLY</code>).",
            "maxLength": 32,
            "type": "string",
            "example": "MONTHLY"
          },
          "vatDate": {
            "format": "date",
            "description": "VAT date. Server-managed (read-only).",
            "type": "string"
          },
          "bookingDueDate": {
            "format": "date",
            "description": "Booking due date returned by accounting. Server-managed (read-only).",
            "type": "string"
          },
          "lastModified": {
            "format": "date-time",
            "description": "Last modification timestamp. Server-managed (read-only).",
            "type": "string"
          },
          "createDate": {
            "format": "date-time",
            "description": "Creation timestamp. Server-managed (read-only).",
            "type": "string"
          },
          "amount": {
            "description": "Invoice total. When <code>usingVAT=false</code> (VAT-exclusive items) this is the gross total = net + VAT; when <code>usingVAT=true</code> (VAT-inclusive items) it is the sum of the gross item amounts (VAT already inside). <strong>Caller-supplied — the server does not recompute it.</strong>",
            "type": "number",
            "example": 1080
          },
          "usingVAT": {
            "description": "Controls whether each item <code>price</code>/<code>amount</code> is <strong>VAT-inclusive (gross)</strong> or <strong>VAT-exclusive (net)</strong>. This is the GUI checkbox <em>\"VAT included in amount of each item\"</em>. <code>true</code> = amounts already include VAT (INCLUDE_VAT); <code>false</code> = VAT is added on top of the net amounts (EXCLUDE_VAT). It does <strong>not</strong> turn VAT on or off — whether VAT applies at all is governed by the company's VAT registration. Use <code>GET /core/latest/company-configuration/including-vat</code> for the company default. <strong>The server stores the amounts you send verbatim and does not recompute them from this flag</strong> — send <code>price</code>/<code>amount</code> consistent with the chosen mode (see the create operation's VAT-handling notes).",
            "default": "false",
            "type": "boolean",
            "example": true
          },
          "usingExportVat": {
            "description": "Export invoice flag — the GUI <em>\"Export\"</em> checkbox. When <code>true</code>, the invoice is treated as an export: every <code>orderItems[].vat.rate</code> must be <code>0</code> (export/zero VAT code), so no VAT is charged. When <code>false</code> (default) the items' normal VAT rates apply. The server does not recompute item VAT from this flag — set the per-item VAT accordingly.",
            "default": "false",
            "type": "boolean",
            "example": false
          },
          "subject": {
            "description": "Free-text invoice subject.",
            "maxLength": 1024,
            "type": "string",
            "example": "Invoice 2026-001"
          },
          "closeAndSignature": {
            "description": "Free-text closing remarks / signature block.",
            "maxLength": 4096,
            "type": "string",
            "example": "Thank you for your business."
          },
          "ourReference": {
            "description": "Internal sender reference.",
            "maxLength": 128,
            "type": "string",
            "example": "ACC-2026"
          },
          "yourReference": {
            "description": "Customer-side reference (e.g. PO number).",
            "maxLength": 128,
            "type": "string",
            "example": "PO-9981"
          },
          "companyCityAndDate": {
            "description": "Header line such as 'Zurich, 28.05.2026'.",
            "maxLength": 256,
            "type": "string",
            "example": "Zurich, 28.05.2026"
          },
          "postMethod": {
            "description": "Distribution channel recorded on the invoice. <strong>Stored only — creating an invoice does not deliver it</strong> (no email/ePost/eBill/print&amp;send). Allowed values: <code>A_POST</code>, <code>B_POST</code>, <code>SEND_EMAIL</code>, <code>PRINT_AND_MANUAL_SEND</code>, <code>EPOST</code>, <code>EBILL</code>.",
            "type": "string",
            "example": "SEND_EMAIL"
          },
          "delivery": {
            "description": "Delivery method label (free text).",
            "maxLength": 64,
            "type": "string",
            "example": "DHL"
          },
          "ibanNumberCHF": {
            "description": "CHF IBAN for payment. Validated by downstream service.",
            "type": "string",
            "example": "CH9300762011623852957"
          },
          "ibanNumberCHW": {
            "description": "WIR-franc IBAN for payment.",
            "type": "string",
            "example": "CH9300762011623852957"
          },
          "wirAcceptanceRate": {
            "description": "WIR acceptance percentage.",
            "type": "number",
            "example": 0
          },
          "referenceNumber": {
            "description": "QR / ISR reference number.",
            "maxLength": 64,
            "type": "string",
            "example": "21 00000 00003 13947 14300 09017"
          },
          "qrInvoice": {
            "description": "When <code>true</code>, the invoice is rendered/booked as a Swiss QR-invoice. Defaults to false.",
            "default": "false",
            "type": "boolean",
            "example": true
          },
          "fromAutoInvoicing": {
            "description": "Indicates the invoice was generated by auto-invoicing. Defaults to false.",
            "default": "false",
            "type": "boolean",
            "example": false
          },
          "fromInvoiceRun": {
            "description": "Indicates the invoice was produced by a recurring invoice run. When <code>true</code>, accounting booking and inventory transactions are skipped. Defaults to false.",
            "default": "false",
            "type": "boolean",
            "example": false
          },
          "invoiceType": {
            "description": "Invoice type. Allowed values: <code>MANUAL</code>, <code>CREDIT_DEBIT</code>.",
            "type": "string",
            "example": "MANUAL"
          },
          "originDistributionMethod": {
            "description": "Origin distribution method. Allowed values: <code>A_POST</code>, <code>B_POST</code>, <code>SEND_EMAIL</code>, <code>PRINT_AND_MANUAL_SEND</code>, <code>EPOST</code>, <code>EBILL</code>.",
            "type": "string",
            "example": "SEND_EMAIL"
          },
          "templateId": {
            "format": "int64",
            "description": "Template id used to create this invoice.",
            "type": "integer",
            "example": 0
          },
          "runHistoryId": {
            "format": "int64",
            "description": "Recurring invoice run history id.",
            "type": "integer",
            "example": 0
          },
          "settledAmount": {
            "description": "Klara-Pay settled amount (online shop only).",
            "type": "number",
            "example": 0
          },
          "bookingNumbers": {
            "description": "Accounting booking-number string. Server-managed (read-only).",
            "type": "string"
          },
          "businessCaseId": {
            "format": "int64",
            "description": "Accounting business case id. Server-managed (read-only).",
            "type": "integer"
          },
          "bookingStatus": {
            "description": "Booking status (e.g. <code>OPEN</code>, <code>PARTIAL</code>, <code>PAID</code>). Server-managed (read-only).",
            "type": "string"
          },
          "bookingMessage": {
            "description": "Optional booking error/info code (e.g. <code>INVALID_SUBSCRIPTION_FOR_ACCOUNTING</code>). Server-managed (read-only).",
            "type": "string"
          },
          "bookingSealed": {
            "description": "Whether the booking has been finalized. Server-managed (read-only).",
            "type": "boolean"
          },
          "fiscalYearHasCreatedAuto": {
            "description": "Whether a fiscal year was auto-created during booking. Server-managed (read-only).",
            "type": "boolean"
          },
          "createBy": {
            "description": "Server-assigned audit user (token subject). Server-managed (read-only).",
            "type": "string"
          }
        }
      },
      "LegalForm": {
        "enum": [
          "LIMITED_LIABILITY",
          "CORPORATION",
          "OR",
          "INDIVIDUALLY_OWNED_COMPANY",
          "ASSOCIATION",
          "SIMPLE_PARTNERSHIP",
          "GENERAL_PARTNERSHIP",
          "LIMITED_PARTNERSHIP",
          "COOPERATIVE_COMPANY",
          "FOUNDATION",
          "IOER"
        ],
        "type": "string"
      },
      "Link": {
        "description": "Link metadata",
        "type": "object",
        "properties": {
          "href": {
            "type": "string"
          }
        }
      },
      "NextInvoiceNumberResponse": {
        "description": "Response wrapper for the next available invoice number for the authenticated company.",
        "type": "object",
        "properties": {
          "nextInvoiceNumber": {
            "format": "int64",
            "description": "The next available invoice number reserved for the authenticated company. Each successful call advances the persisted counter; the value is therefore unique per call.",
            "type": "integer",
            "example": 2026001
          }
        }
      },
      "OnlinePlatform": {
        "description": "An online platform.",
        "type": "object",
        "properties": {
          "id": {
            "description": "Id of this Online platform. Does not need to be included when creating Customer.",
            "type": "string",
            "readOnly": true,
            "example": "1"
          },
          "platformName": {
            "allOf": [
              {
                "$ref": "#/components/schemas/OnlinePlatformType"
              },
              {
                "description": "Name of the platform that this customer uses",
                "example": "FACEBOOK"
              }
            ]
          },
          "platformValue": {
            "description": "Url of customer's online platform/webpage",
            "type": "string",
            "example": "www.linkedin.com/abc"
          }
        }
      },
      "OnlinePlatformType": {
        "enum": [
          "FACEBOOK",
          "GOOGLE_PLUS",
          "INSTAGRAM",
          "LINKEDIN",
          "PINTEREST",
          "SKYPE",
          "SNAPCHAT",
          "TWITTER",
          "WHATSAPP",
          "XING",
          "YOUTUBE"
        ],
        "type": "string"
      },
      "OrderDocument": {
        "description": "An order-management document — offer, confirmation, delivery-note, invoice, credit note or recurring invoice template. The polymorphic discriminator <code>orderType</code> identifies the concrete subtype. Server-managed fields (<code>vatDate</code>, <code>lastModified</code>, <code>createDate</code>) are populated on the response.",
        "type": "object",
        "properties": {
          "id": {
            "format": "int64",
            "description": "Document id (database primary key).",
            "type": "integer",
            "example": 1234
          },
          "orderType": {
            "description": "Polymorphic discriminator. Allowed values: <code>OFFER</code>, <code>CONFIRMATION</code>, <code>DELIVERY_NOTE</code>, <code>INVOICE</code>, <code>CREDIT_NOTE</code>, <code>FRIENDLY_REMINDER</code>, <code>FIRST_REMINDER</code>, <code>SECOND_REMINDER</code>, <code>PAYSLIP</code>, <code>RECURRING_INVOICE_TEMPLATE</code>.",
            "type": "string",
            "example": "DELIVERY_NOTE"
          },
          "status": {
            "description": "Document status (subtype-specific). For invoices: <code>DRAFT</code>, <code>INVOICED</code>, <code>SENT</code>, <code>PAID</code>, <code>CANCELLED</code>.",
            "type": "string",
            "example": "SENT"
          },
          "documentDate": {
            "format": "date",
            "description": "Document creation/business date (ISO 8601).",
            "type": "string",
            "example": "2026-05-28"
          },
          "issuedDate": {
            "format": "date",
            "description": "Date the document was issued (ISO 8601).",
            "type": "string",
            "example": "2026-05-28"
          },
          "amount": {
            "description": "Document gross total (incl. VAT when applicable).",
            "type": "number",
            "example": 500
          },
          "ourReference": {
            "description": "Internal sender reference.",
            "type": "string",
            "example": "ACC-2026"
          },
          "yourReference": {
            "description": "Customer-side reference (e.g. PO number).",
            "type": "string",
            "example": "PO-9981"
          },
          "subject": {
            "description": "Free-text document subject.",
            "type": "string",
            "example": "Delivery note 377"
          },
          "closeAndSignature": {
            "description": "Free-text closing remarks / signature block.",
            "type": "string",
            "example": "Thank you for your business."
          },
          "companyCityAndDate": {
            "description": "Header line such as 'Zurich, 28.05.2026'.",
            "type": "string",
            "example": "Zurich, 28.05.2026"
          },
          "usingVAT": {
            "description": "Whether VAT is applied on this document.",
            "default": "false",
            "type": "boolean",
            "example": true
          },
          "vatDate": {
            "format": "date",
            "description": "VAT date. Server-managed (read-only).",
            "type": "string"
          },
          "printedFileId": {
            "description": "Document file id of the rendered PDF (if any).",
            "type": "string",
            "example": "1771764"
          }
        }
      },
      "OrderNextNumberResult": {
        "type": "object",
        "properties": {
          "nextOrderNumber": {
            "format": "int32",
            "description": "The next available business order number for the authenticated company. Reserved exclusively for this call — use it as the orderNumber when subsequently creating the order. Gaps may appear in the sequence if the order creation fails after this call.",
            "type": "integer",
            "example": 10041
          }
        }
      },
      "OrderNumberingConfiguration": {
        "type": "object",
        "properties": {
          "orderType": {
            "allOf": [
              {
                "$ref": "#/components/schemas/OrderType"
              },
              {
                "description": "Order-document type this configuration applies to.",
                "example": "INVOICE"
              }
            ]
          },
          "orderNumberingType": {
            "allOf": [
              {
                "$ref": "#/components/schemas/OrderNumberingType"
              },
              {
                "description": "Strategy used to assign document numbers. <code>STANDARD</code>: server auto-increments from <code>startingNumber</code>; <code>MANUAL</code>: caller must supply a number in <code>POST /invoices</code>; <code>CUSTOMISED</code>: caller must supply a code matching <code>format</code>.",
                "example": "STANDARD"
              }
            ]
          },
          "startingNumber": {
            "format": "int64",
            "description": "The first number in the auto-increment sequence (relevant for STANDARD). Null when not configured.",
            "type": "integer",
            "example": 1000
          },
          "increment": {
            "format": "int64",
            "description": "Step size between successive auto-incremented numbers (relevant for STANDARD). Null when not configured.",
            "type": "integer",
            "example": 1
          },
          "format": {
            "description": "Alphanumeric format pattern for CUSTOMISED numbering (e.g. <code>INV-{YYYY}-{SEQ}</code>). Null when not configured.",
            "type": "string",
            "example": "INV-2026-{SEQ}"
          }
        }
      },
      "OrderNumberingResult": {
        "type": "object",
        "properties": {
          "orderType": {
            "allOf": [
              {
                "$ref": "#/components/schemas/OrderType"
              },
              {
                "description": "Order-document type this result applies to.",
                "example": "INVOICE"
              }
            ]
          },
          "orderNumberingType": {
            "allOf": [
              {
                "$ref": "#/components/schemas/OrderNumberingType"
              },
              {
                "description": "Numbering strategy for this document type: STANDARD (server auto-assigns), MANUAL (caller supplies invoiceCode), CUSTOMISED (caller supplies formatted code).",
                "example": "STANDARD"
              }
            ]
          },
          "startingNumber": {
            "format": "int64",
            "description": "Starting sequence number for STANDARD and CUSTOMISED strategies.",
            "type": "integer",
            "example": 1000
          },
          "increment": {
            "format": "int64",
            "description": "Step size between successive auto-incremented numbers.",
            "type": "integer",
            "example": 1
          },
          "format": {
            "description": "Alphanumeric prefix for CUSTOMISED numbering (the server appends the sequence number).",
            "type": "string",
            "example": "INV-2026-"
          },
          "documentNumber": {
            "format": "int64",
            "description": "The next document number to use (the sequence integer). For INVOICE this counter is persisted on every call — do not call speculatively.",
            "type": "integer",
            "example": 1001
          },
          "documentCode": {
            "description": "The next document code to use as invoiceCode / offerCode. For STANDARD and MANUAL this equals String.valueOf(documentNumber); for CUSTOMISED it equals format + documentNumber (e.g. \"INV-2026-1001\").",
            "type": "string",
            "example": "1001"
          }
        }
      },
      "OrderNumberingType": {
        "description": "Strategy used to assign document numbers for an order type. <code>STANDARD</code> — server auto-increments; <code>MANUAL</code> — caller supplies the number; <code>CUSTOMISED</code> — caller supplies a formatted code matching the configured pattern.",
        "enum": [
          "STANDARD",
          "MANUAL",
          "CUSTOMISED"
        ],
        "type": "string"
      },
      "OrderType": {
        "description": "Order-management document type. Used as the discriminator on <code>OrderDocument.orderType</code>.",
        "enum": [
          "OFFER",
          "CONFIRMATION",
          "DELIVERY_NOTE",
          "INVOICE",
          "CREDIT_NOTE",
          "FRIENDLY_REMINDER",
          "FIRST_REMINDER",
          "SECOND_REMINDER",
          "PAYSLIP",
          "RECURRING_INVOICE_TEMPLATE"
        ],
        "type": "string"
      },
      "PaymentType": {
        "enum": [
          "BANK",
          "PAYINSLIP",
          "CASH"
        ],
        "type": "string"
      },
      "PayslipSalaryItem": {
        "description": "A salary item added to a payslip, with its server-assigned id.",
        "type": "object",
        "properties": {
          "id": {
            "format": "int64",
            "description": "Server-assigned id of the added salary item (present in the response only).",
            "type": "integer",
            "example": 778812
          },
          "code": {
            "description": "Salary-type code of the added salary item.",
            "type": "string",
            "example": "1005"
          },
          "salaryItemValues": {
            "allOf": [
              {
                "$ref": "#/components/schemas/PayslipSalaryItemValues"
              },
              {
                "description": "The numeric value fields (Base / Percent / Quantity / Amount) of the added salary item."
              }
            ]
          },
          "remark": {
            "description": "Free-text comment attached to the salary item (GUI \"Comments\").",
            "type": "string",
            "example": "Adjustment for March"
          }
        }
      },
      "PayslipSalaryItemRequest": {
        "description": "The salary item to add to a payslip: the salary-type code plus its numeric values and an optional comment.",
        "required": [
          "code"
        ],
        "type": "object",
        "properties": {
          "code": {
            "description": "Salary-type code identifying the item to add. Must be one of the codes returned by GET /payroll/employees/{employeeId}/addable-salary-items (salaryItems[].code).",
            "maxLength": 64,
            "pattern": "\\S",
            "type": "string",
            "example": "1005",
            "nullable": false
          },
          "salaryItemValues": {
            "allOf": [
              {
                "$ref": "#/components/schemas/PayslipSalaryItemValues"
              },
              {
                "description": "The numeric value fields (Base / Percent / Quantity / Amount). Only fields listed in the salary item's editableFields, which are also returned by GET /payroll/employees/{employeeId}/addable-salary-items (salaryItems[].editableFields), should be provided."
              }
            ]
          },
          "remark": {
            "description": "Optional free-text comment (GUI \"Comments\").",
            "maxLength": 1024,
            "type": "string",
            "example": "Adjustment for March"
          }
        }
      },
      "PayslipSalaryItemValues": {
        "description": "Numeric value fields of a salary item (GUI Base / Percent / Quantity / Amount). Only fields listed in the salary item's editableFields may be provided.",
        "type": "object",
        "properties": {
          "baseValue": {
            "description": "GUI \"Base\" value.",
            "type": "number",
            "example": 5000
          },
          "rate": {
            "description": "GUI \"Percent (%)\" value, expressed as a decimal multiplier — NOT a percentage number. 1 = 100%, 0.5 = 50%, 2 = 200%. If GUI implementation wants to keep a normal percentage input for the user (typing 50 for 50%) instead of a multiplier (0.5), it must divide that input by 100 before sending it here (50 / 100 = 0.5).",
            "type": "number",
            "example": 0.5
          },
          "quantity": {
            "description": "GUI \"Quantity\" value.",
            "type": "number",
            "example": 1
          },
          "value": {
            "description": "GUI \"Amount\" value.",
            "type": "number",
            "example": 425
          }
        }
      },
      "PeriodOfYear": {
        "description": "Reporting period of a VAT clearing report.",
        "enum": [
          "Q1",
          "Q2",
          "Q3",
          "Q4",
          "S1",
          "S2",
          "YEAR_NET_TAX_RATE",
          "YEAR_EFFECTIVE"
        ],
        "type": "string",
        "example": "Q1"
      },
      "Person": {
        "description": "A partner person.",
        "required": [
          "correspondence",
          "salutation",
          "firstName",
          "lastName"
        ],
        "type": "object",
        "properties": {
          "website": {
            "description": "The website address of this customer",
            "type": "string",
            "example": "www.my-company.com"
          },
          "categories": {
            "description": "Add one or more categories to this customer that you can use as filter criteria for selecting partners",
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "onlinePlatforms": {
            "description": "The list of online platforms that this customer uses",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/OnlinePlatform"
            }
          },
          "language": {
            "description": "The main language that this partner uses, valid values is [en, de, fr, it]",
            "type": "string",
            "example": "en"
          },
          "responsibleCounterpart": {
            "description": "The name of a contact person for this customer",
            "type": "string",
            "example": "Mr. Marc"
          },
          "correspondence": {
            "allOf": [
              {
                "$ref": "#/components/schemas/Correspondence"
              },
              {
                "description": "The preferred method of correspondence, how this customer wants to receive the pay slips by default",
                "example": "MAIL",
                "nullable": false
              }
            ]
          },
          "id": {
            "description": "Id of this person. Does not need to be included when creating customer",
            "type": "string",
            "example": "1"
          },
          "salutation": {
            "allOf": [
              {
                "$ref": "#/components/schemas/Salutation"
              },
              {
                "description": "Salutation for this person, valid values is: [MALE, FEMALE, MALE_FEMALE, FAMILY]",
                "example": "MALE",
                "nullable": false
              }
            ]
          },
          "firstName": {
            "description": "First name of this person",
            "pattern": "\\S",
            "type": "string",
            "example": "John",
            "nullable": false
          },
          "lastName": {
            "description": "Last name of this person",
            "pattern": "\\S",
            "type": "string",
            "example": "Henry",
            "nullable": false
          },
          "birthday": {
            "format": "date",
            "description": "Birth date of this person in ISO 8601 format (yyyy-MM-dd)",
            "type": "string",
            "example": "2020-01-20"
          },
          "addresses": {
            "description": "Address list of this person",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Address"
            }
          },
          "phones": {
            "description": "Phone number list of this person",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Phone"
            }
          },
          "emails": {
            "description": "Email list of this person",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Email"
            }
          },
          "personNumber": {
            "description": "This is a number the KLARA user can give to this customer/partner/supplier",
            "type": "string"
          }
        }
      },
      "Phone": {
        "description": "A phone number.",
        "required": [
          "phoneNumber",
          "type"
        ],
        "type": "object",
        "properties": {
          "id": {
            "description": "Id of this Phone. <strong>Does not need to be included</strong> when creating customer.",
            "type": "string",
            "example": "1"
          },
          "phoneNumber": {
            "type": "string",
            "example": 41783334444,
            "nullable": false
          },
          "type": {
            "allOf": [
              {
                "$ref": "#/components/schemas/PhoneType"
              },
              {
                "description": "Type of this phone number. For company, only <strong>OFFICE</strong> type is supported",
                "enum": [
                  "PRIVATE",
                  "OFFICE",
                  "MOBILE",
                  "WORK"
                ],
                "example": "PRIVATE",
                "nullable": false
              }
            ]
          }
        }
      },
      "PhoneType": {
        "enum": [
          "PRIVATE",
          "OFFICE",
          "FAX",
          "WORK",
          "MOBILE"
        ],
        "type": "string"
      },
      "PriceCategory": {
        "description": "A price category effective in a price period.",
        "type": "object",
        "properties": {
          "name": {
            "description": "Name of the price category",
            "type": "string"
          },
          "price": {
            "description": "Effective price of this price category",
            "pattern": "^\\d{1,19}([.]\\d{1,2})?$",
            "type": "number"
          }
        }
      },
      "PricePeriod": {
        "description": "A price period to apply for an article.",
        "type": "object",
        "properties": {
          "validFrom": {
            "format": "date",
            "description": "The price period is valid from this time",
            "type": "string"
          },
          "validTo": {
            "format": "date",
            "description": "The price period is invalid after this time",
            "type": "string",
            "readOnly": true
          },
          "price": {
            "description": "The price used for an article within this price period",
            "pattern": "^\\d{1,19}([.]\\d{1,2})?$",
            "type": "number"
          },
          "priceCategories": {
            "description": "List of price categories effective for this price period",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PriceCategory"
            }
          }
        }
      },
      "PricePlan": {
        "enum": [
          "SINGLE",
          "VOLUME",
          "MONTHLY",
          "QUARTERLY",
          "YEARLY",
          "FREE",
          "PAY_PER_USE"
        ],
        "type": "string"
      },
      "Product": {
        "description": "A product in KLARA widget store. Enable different features for users.",
        "required": [
          "code",
          "name"
        ],
        "type": "object",
        "properties": {
          "code": {
            "description": "Identifier code for each product-should be unique across all products",
            "pattern": "\\S",
            "type": "string",
            "example": "PRINTANDSENT",
            "nullable": false
          },
          "name": {
            "description": "The name of the product",
            "type": "string",
            "example": "Print and sent"
          }
        }
      },
      "ProductType": {
        "description": "Type of product used for an article",
        "enum": [
          "SERVICE",
          "PRODUCTION",
          "TRADE",
          "OTHER",
          "GIFT_CARD",
          "PREPAYMENT"
        ],
        "type": "string"
      },
      "PublicAPIToken": {
        "description": "A public api token object. This object holds info of tokens that can be used to access KLARA Public API",
        "type": "object",
        "properties": {
          "access_token": {
            "description": "Token used to access KLARA Public API endpoints, should be place at Authorization header of request. Access token is valid only for one company tenant",
            "type": "string"
          },
          "expires_in": {
            "format": "int64",
            "description": "Amount of time in seconds left that the access token is valid for",
            "type": "integer"
          },
          "refresh_expires_in": {
            "format": "int64",
            "description": "Amount of time in seconds left that the refresh token is valid for",
            "type": "integer"
          },
          "refreshToken": {
            "description": "Token used to renew the access token",
            "type": "string"
          },
          "token_type": {
            "description": "Type of access token that should be included in the Authorziation header of each request",
            "type": "string"
          }
        }
      },
      "PublicApiAccount": {
        "description": "A master account from Klara's global chart of accounts.",
        "type": "object",
        "properties": {
          "id": {
            "format": "int64",
            "description": "Internal identifier of the master account.",
            "type": "integer",
            "example": 42
          },
          "code": {
            "format": "int32",
            "description": "Numeric account code as printed on the chart of accounts.",
            "type": "integer",
            "example": 1020
          },
          "name": {
            "description": "Localized account name. Resolved against the request's <code>Accept-Language</code> and, when <code>legal-form</code> is supplied, against the legal-form-specific translation.",
            "type": "string",
            "example": "Bank"
          },
          "tags": {
            "description": "Free-text keyword tokens associated with the account, used by client-side search. Tokens are delimited by comma or semicolon.",
            "type": "string",
            "example": "bank;konto"
          },
          "links": {
            "description": "Linked-account references used by report computations.",
            "type": "string",
            "example": "bank_account"
          },
          "accountReportLinks": {
            "description": "Report-grouping references used to assemble balance-sheet / P&L groupings.",
            "type": "string",
            "example": "bank_account"
          },
          "initialBalanceSheet": {
            "description": "True when the account is part of the initial opening-balance sheet.",
            "type": "boolean",
            "example": false
          },
          "visibleFirstFiscalYear": {
            "description": "True when the account is visible during the first fiscal year of a new company.",
            "type": "boolean",
            "example": true
          },
          "visibleFromSecondFiscalYear": {
            "description": "True when the account becomes visible from the second fiscal year onwards.",
            "type": "boolean",
            "example": true
          },
          "vatAccount": {
            "description": "True when the account is reserved for VAT postings.",
            "type": "boolean",
            "example": false
          },
          "accountReportFilters": {
            "description": "Report-grouping configuration rows attached to this account.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PublicApiAccountReportFilter"
            }
          },
          "notManuallyAdded": {
            "description": "True when the account was seeded automatically (not added by an end user).",
            "type": "boolean",
            "example": true
          }
        }
      },
      "PublicApiAccountDisplaying": {
        "description": "One account-displaying row for the manual-booking picker. Each row is a flat (account × optional sub-account) combination. When the account has no sub-account definitions, exactly one row is emitted with the link fields set to <code>null</code>. When the account has sub-account link specifications, one row is emitted per individual sub-account entry, numbered sequentially across all link types with a 0-based counter suffix.",
        "type": "object",
        "properties": {
          "combinedCode": {
            "description": "Picker key. <code>\"&lt;accountCode&gt;-&lt;i&gt;\"</code> when a sub-account exists (e.g. <code>\"1020-0\"</code>); the bare account code string (e.g. <code>\"3000\"</code>) when <code>linkType</code> is <code>null</code>. The suffix index is a flat 0-based counter per account, spanning all link types in declaration order.",
            "type": "string",
            "example": "1020-0"
          },
          "combinedName": {
            "description": "Picker label. <code>\"&lt;accountName&gt; (&lt;subAccountDisplay&gt;)\"</code> when a sub-account exists (e.g. <code>\"Bank (UBS)\"</code>); the bare account name (e.g. <code>\"Bürobedarf\"</code>) when <code>linkType</code> is <code>null</code>.",
            "type": "string",
            "example": "Bank (UBS)"
          },
          "parentAccount": {
            "allOf": [
              {
                "$ref": "#/components/schemas/PublicApiAccount"
              },
              {
                "description": "The full master account this row belongs to. Identical across every row produced for the same account."
              }
            ]
          },
          "linkType": {
            "description": "Link-type category. Identifies the kind of entity the sub-account refers to. Common values: <code>VAT_RATE</code>, <code>VAT_CASE</code>, <code>BANK</code>, <code>CUSTOMER</code>, <code>SUPPLIER</code>, <code>EMPLOYEE</code>, <code>SOCIAL_INSURANCE</code>, <code>TAX_AT_SOURCE</code>, <code>EQUITY</code>, <code>TANGIBLE_ASSET</code>, <code>IMMOBILE_TANGIBLE_ASSET</code>, <code>UNFINISHED_PRODUCTS</code>, <code>FINISHED_PRODUCTS</code>, <code>NON_BILLED_SERVICES</code>, <code>INVENTORY_CHANGE_MATERIAL</code>, <code>INVENTORY_CHANGE_GOODS</code>, <code>LONG_TERM_INTEREST_BEARING</code>, <code>OTHER_LONG_TERM_INTEREST_BEARING</code>, <code>GIFT_CARD</code>, <code>VARIOUS</code>. <code>null</code> when the account has no sub-account definitions.",
            "type": "string",
            "example": "BANK"
          },
          "linkDisplay": {
            "description": "Human-readable label for the link type in the requested <code>Accept-Language</code>. Falls back to the German label when no translation exists for the requested language. <code>null</code> when <code>linkType</code> is <code>null</code>.",
            "type": "string",
            "example": "Bank account"
          },
          "linkOptional": {
            "description": "<code>true</code> when the sub-account selection is optional for the user (link keys are separated by <code>;</code> in the account definition); <code>false</code> when selecting a sub-account is mandatory (link keys separated by <code>,</code>); <code>null</code> when the account has no sub-account definitions.",
            "type": "boolean",
            "example": false
          },
          "specificationItem": {
            "allOf": [
              {
                "$ref": "#/components/schemas/PublicApiFieldEntry"
              },
              {
                "description": "The resolved sub-account entry for this row. <code>null</code> when the account has no sub-account definitions."
              }
            ]
          }
        }
      },
      "PublicApiAccountReportFilter": {
        "description": "Report-grouping configuration row attached to a master account.",
        "type": "object",
        "properties": {
          "display": {
            "description": "Human-readable label of the report bucket this account contributes to.",
            "type": "string",
            "example": "Operating expenses"
          },
          "linkAccountValue": {
            "description": "Underlying linked-account value used by the accounting engine to resolve the bucket.",
            "type": "string",
            "example": "6000"
          }
        }
      },
      "PublicApiAccountingCompany": {
        "description": "Accounting configuration of one company — dunning waiting periods plus the canonical company URI.",
        "type": "object",
        "properties": {
          "id": {
            "format": "int64",
            "description": "Internal id of the accounting-configuration row. Null when no configuration has been persisted yet for the company.",
            "type": "integer",
            "example": 17
          },
          "companyUri": {
            "description": "Canonical compensation-side URI of the company, of the form /luz_compensation/api/{tenant}/companies/{companyId}.",
            "type": "string",
            "example": "/luz_compensation/api/c60d31fa-f335-4957-872a-90b035632081/companies/1"
          },
          "waitingDunningTime": {
            "format": "int64",
            "description": "Number of days to wait after the invoice due date before starting the dunning cycle. Defaults to 5 when no configuration exists yet.",
            "type": "integer",
            "example": 5
          },
          "dunningWaitingTimeLevelOne": {
            "format": "int64",
            "description": "Days to wait between the level-1 dunning notice and the level-2 escalation. Defaults to 10 when no configuration exists yet.",
            "type": "integer",
            "example": 10
          },
          "dunningWaitingTimeLevelTwo": {
            "format": "int64",
            "description": "Days to wait between the level-2 dunning notice and the level-3 escalation. Defaults to 10 when no configuration exists yet.",
            "type": "integer",
            "example": 10
          },
          "dunningWaitingTimeLevelThree": {
            "format": "int64",
            "description": "Days to wait between the level-3 dunning notice and the final escalation. Defaults to 10 when no configuration exists yet.",
            "type": "integer",
            "example": 10
          }
        }
      },
      "PublicApiArticleSetItem": {
        "type": "object",
        "properties": {
          "id": {
            "description": "Id of the article set",
            "type": "string",
            "example": "1"
          },
          "articleName": {
            "description": "Article name of the article",
            "type": "string",
            "example": "Mobile phone"
          },
          "number": {
            "description": "The number of the article",
            "type": "string",
            "example": "1"
          },
          "productType": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ProductType"
              },
              {
                "description": "Product type of the article",
                "example": "PRODUCTION"
              }
            ]
          },
          "price": {
            "description": "Price of the article",
            "type": "number"
          },
          "vat": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ArticleVat"
              },
              {
                "description": "Vat of the article"
              }
            ]
          },
          "optionValues": {
            "description": "Options for the set item if it is a variant",
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "href": {
            "description": "Reference resource link",
            "type": "string",
            "example": "https://api.klara.ch/core/latest/articles/1"
          }
        }
      },
      "PublicApiBookingDetail": {
        "description": "One debit or credit line of a booking.",
        "required": [
          "accountCode",
          "crdrType",
          "description",
          "amount",
          "tags",
          "bookingTypeCode"
        ],
        "type": "object",
        "properties": {
          "id": {
            "format": "int64",
            "description": "Internal id of the booking detail. Assigned by the server on creation; omit when sending a new booking.",
            "type": "integer",
            "example": 1001
          },
          "accountCode": {
            "format": "int32",
            "description": "Ledger account number the amount is posted to (Swiss SME chart of accounts).",
            "minimum": 1,
            "type": "integer",
            "example": 1020
          },
          "crdrType": {
            "description": "Whether this line is a credit or a debit. Allowed values: CR, DR.",
            "type": "string",
            "example": "DR",
            "nullable": false
          },
          "description": {
            "description": "Free-text description shown on the journal report.",
            "pattern": "\\S",
            "type": "string",
            "example": "Office supplies — invoice 2024-019",
            "nullable": false
          },
          "amount": {
            "description": "Absolute posting amount in the company main currency. Always positive; sign is carried by crdrType.",
            "type": "number",
            "example": 150,
            "nullable": false
          },
          "partialPaymentAmount": {
            "description": "Amount already paid against this line — only used for open-position bookings (invoices, credit notes).",
            "type": "number",
            "example": 0
          },
          "tags": {
            "description": "Comma-separated list of string tags. Each tag is free-form and should represent a topic that the booking line should be associated with. Provide at least one tag per line.",
            "type": "string",
            "example": "project-alpha,q2",
            "nullable": false
          },
          "links": {
            "description": "Comma-separated list of structured links of entities that are considered the sub-accounts associated with an account code when making a booking line.This string can be empty when no sub-account is required for the current account code of the booking line.Each link has the format <code>key:uri-path</code>. <strong>Important:</strong> the exact URI values — including the tenant UUID and company ID segments — are returned verbatim by <code>GET /core/v1/accounting/accounts/account-displaying</code> in the account's <code>specificationItem.link</code> field; copy them as-is, do not construct them manually.<br/><br/><strong>Supported link type keys:</strong><br/><em>Bank / cash sub-accounts</em> (secondary dropdown in GUI for accounts 1000, 1020, 1030, 1040, and similar):<br/><ul><li><code>bank_account</code> — company bank account; URI from <code>/luzfin_finance/api/{tenant}/companies/{cid}/bank-accounts/{id}</code></li><li><code>cash</code> — cash register; URI from <code>/luz_accounting/api/{tenant}/companies/{cid}/cash/{id}</code></li><li><code>transfer_account</code> — transfer account; URI from <code>/luz_accounting/api/{tenant}/companies/{cid}/transfer/{id}</code></li><li><code>interest_bearing_current_account</code> — interest-bearing current account; URI from <code>/luz_accounting/api/{tenant}/companies/{cid}/interest-bearing-current/{id}</code></li><li><code>non_interest_bearing_current_account</code> — non-interest-bearing current account; URI from <code>/luz_accounting/api/{tenant}/companies/{cid}/non-interest-bearing/{id}</code></li></ul><em>Counterpart links</em> (customer / supplier / employee sub-ledger):<br/><ul><li><code>customer</code> — accounts-receivable customer; URI from <code>/luzfin_finance/api/{tenant}/companies/{cid}/customers/{id}</code></li><li><code>supplier</code> — accounts-payable supplier; URI from <code>/luzfin_finance/api/{tenant}/companies/{cid}/customers/{id}</code></li><li><code>employee</code> — employee (payroll/HR); URI from <code>/luz_compensation/api/{tenant}/companies/{cid}/employees/{id}</code></li></ul><em>Tax / VAT links</em>:<br/><ul><li><code>vat_case</code> — VAT case; URI from <code>/luz_accounting/api/vat-cases/{id}</code> (obtain from <code>GET /core/latest/vat-cases</code>)</li><li><code>vat_rate</code> — master VAT rate; URI from <code>/luz_accounting/api/master-vats/{id}</code> (obtain from <code>GET /core/v1/accounting/master-vats</code>)</li><li><code>social_insurance</code> — social insurance contract; URI from <code>/luz_compensation/api/{tenant}/companies/{cid}/insurance-contracts/{id}</code></li><li><code>tax_at_source</code> — tax-at-source (withholding tax) state; URI from <code>/luz_person/api/states/{id}</code></li></ul><em>Asset / liability / equity links</em>:<br/><ul><li><code>financial_asset</code> — financial asset; URI from <code>/luz_accounting/api/{tenant}/companies/{cid}/financial-asset/{id}</code></li><li><code>intangible_asset</code> — intangible asset; URI from <code>/luz_accounting/api/{tenant}/companies/{cid}/intangible-asset/{id}</code></li><li><code>equity</code> — equity account; URI from <code>/luz_accounting/api/{tenant}/companies/{cid}/equity/{id}</code></li><li><code>long_term_interest_bearing_liability</code> — long-term loan; URI from <code>/luz_accounting/api/{tenant}/companies/{cid}/long-term-interest-bearing/{id}</code></li><li><code>statutory_profit_reserve</code> — statutory profit reserve; URI from <code>/luz_accounting/api/{tenant}/companies/{cid}/statutory-profit-reserve/{id}</code></li><li><code>deferrals</code> — accrual/deferral position; URI from <code>/luz_accounting/api/{tenant}/companies/{cid}/deferral/{id}</code></li></ul><em>Revenue / inventory / other links</em>:<br/><ul><li><code>gift_card</code> — gift card; URI from <code>/luz_accounting/api/{tenant}/companies/{cid}/gift-cards/{id}</code></li><li><code>not_billed_services</code> — unbilled service position; URI from <code>/luz_accounting/api/{tenant}/companies/{cid}/not-billed-services/{id}</code></li><li><code>various</code> — miscellaneous counterpart; URI from <code>/luz_accounting/api/{tenant}/companies/{cid}/various/{id}</code></li><li><code>inventory_change_goods</code> — inventory type (static); URI: <code>/luz_accounting/api/inventory-types/inventory-change-goods</code></li><li><code>inventory_change_material</code> — inventory type (static); URI: <code>/luz_accounting/api/inventory-types/inventory-change-material</code></li><li><code>non_billed_services</code> — inventory type (static); URI: <code>/luz_accounting/api/inventory-types/non-billed-services</code></li><li><code>finished_products</code> — inventory type (static); URI: <code>/luz_accounting/api/inventory-types/finished-products</code></li><li><code>unfinished_products</code> — inventory type (static); URI: <code>/luz_accounting/api/inventory-types/unfinished-products</code></li></ul>Multiple entries are comma-separated. Leave empty when none apply.",
            "type": "string",
            "example": "bank_account:/luzfin_finance/api/388c822c-7860-41ae-94ac-330684bb63e0/companies/1/bank-accounts/85,vat_case:/luz_accounting/api/vat-cases/1"
          },
          "seq": {
            "format": "int32",
            "description": "Ordering of the line inside the booking, starting at 0.",
            "type": "integer",
            "example": 0
          },
          "vatAccountCode": {
            "format": "int32",
            "description": "GUI-style VAT input, used only with <code>autoCalculateVat=true</code>: the account the automatically generated VAT counterpart line is posted to (the GUI \"VAT account\", e.g. 1170). Required on a VAT-bearing line when the line carries a <code>vat_rate</code> link and omits its own VAT line. Ignored when <code>autoCalculateVat</code> is false (caller pre-splits the lines).",
            "type": "integer",
            "example": 1170
          },
          "vatTypeDescription": {
            "description": "How VAT is recorded for this line. Allowed values: INCLUSIVE, EXCLUSIVE, NONE.",
            "type": "string",
            "example": "INCLUSIVE"
          },
          "vatBookingDetailLink": {
            "description": "URI of the companion VAT booking detail, when one was generated automatically.",
            "type": "string"
          },
          "vatAmount": {
            "description": "VAT amount carried on this line, in the company main currency.",
            "type": "number",
            "example": 11.4
          },
          "vatRate": {
            "description": "Effective VAT rate (percent) applied to this line.",
            "type": "number",
            "example": 7.7
          },
          "vatRateDisplay": {
            "description": "Display string of the VAT rate as rendered in the UI.",
            "type": "string",
            "example": "7.7%"
          },
          "vatBookingDetail": {
            "description": "True when this line is the automatically generated VAT counterpart of another line.",
            "type": "boolean",
            "example": false
          },
          "bookingTypeCode": {
            "description": "Business meaning of the booking line. Allowed values include GENERAL_LEDGER, AR_INVOICE, AP_INVOICE, AR_PAYMENT, AP_PAYMENT, AR_CREDIT_NOTE, AP_CREDIT_NOTE.",
            "type": "string",
            "example": "GENERAL_LEDGER",
            "nullable": false
          },
          "openPositionStatus": {
            "description": "Lifecycle of the open position represented by this line. Allowed values include OPEN, PARTIALLY_PAID, PAID, CLOSED.",
            "type": "string",
            "example": "OPEN"
          },
          "creditorReference": {
            "description": "Creditor reference (QR-bill / ISO 11649) attached to the open position.",
            "type": "string"
          },
          "isrReference": {
            "description": "ISR reference number attached to the open position.",
            "type": "string"
          },
          "isrMember": {
            "description": "ISR participant (member) number of the creditor.",
            "type": "string"
          },
          "partnerIban": {
            "description": "IBAN of the counterpart used for outgoing payments.",
            "type": "string"
          },
          "endToEndId": {
            "description": "Pain.001 end-to-end id, propagated to the outgoing payment instruction.",
            "type": "string"
          },
          "isExcludeVatAmount": {
            "description": "When true, the gross amount on this line excludes VAT; otherwise it includes VAT.",
            "type": "boolean",
            "example": false
          },
          "foreignCurrencyAmount": {
            "description": "Posting amount in the foreign currency, when the line is booked in a non-main currency.",
            "type": "number"
          },
          "foreignCurrencyUnit": {
            "description": "ISO 4217 code of the foreign currency.",
            "type": "string",
            "example": "EUR"
          },
          "paidDate": {
            "format": "date-time",
            "description": "Date on which the open position was settled (yyyy-MM-ddT00:00:00Z).",
            "type": "string",
            "example": "2024-06-15T00:00:00Z"
          },
          "dueDate": {
            "format": "date-time",
            "description": "Date on which the open position becomes overdue (yyyy-MM-ddT00:00:00Z).",
            "type": "string",
            "example": "2024-06-30T00:00:00Z"
          },
          "paymentDate": {
            "format": "date-time",
            "description": "Date on which the payment instruction is scheduled (yyyy-MM-ddT00:00:00Z).",
            "type": "string",
            "example": "2024-06-28T00:00:00Z"
          },
          "servicePeriodFrom": {
            "format": "date-time",
            "description": "Start of the service period covered by the line (yyyy-MM-ddT00:00:00Z).",
            "type": "string",
            "example": "2024-06-01T00:00:00Z"
          },
          "servicePeriodTo": {
            "format": "date-time",
            "description": "End of the service period covered by the line (yyyy-MM-ddT00:00:00Z).",
            "type": "string",
            "example": "2024-06-30T00:00:00Z"
          },
          "paymentPercentage": {
            "description": "Percentage of the open-position amount already settled.",
            "type": "number",
            "example": 0
          },
          "isDunningBlocked": {
            "description": "When true, dunning reminders are suppressed for this open position.",
            "type": "boolean",
            "example": false
          }
        }
      },
      "PublicApiBookingHeader": {
        "description": "A booking (manual journal entry) together with its debit/credit lines.",
        "required": [
          "documentDate",
          "bookingDate",
          "bookingDetails"
        ],
        "type": "object",
        "properties": {
          "id": {
            "format": "int64",
            "description": "Internal id of the booking. Assigned by the server on creation; omit when sending a new booking.",
            "type": "integer",
            "example": 12345
          },
          "companyId": {
            "format": "int64",
            "description": "Internal id of the company this booking belongs to. Filled by the server from the caller's session; ignored on input.",
            "type": "integer",
            "example": 1
          },
          "documentDate": {
            "format": "date-time",
            "description": "Date printed on the underlying document, e.g. supplier invoice date (yyyy-MM-ddT00:00:00Z).",
            "type": "string",
            "example": "2024-06-15T00:00:00Z"
          },
          "bookingDate": {
            "format": "date-time",
            "description": "Effective accounting date of the booking; must fall inside an open fiscal year unless confirmDontMindClosingFiscalYear is set (yyyy-MM-ddT00:00:00Z).",
            "type": "string",
            "example": "2024-06-15T00:00:00Z",
            "nullable": false
          },
          "documentIds": {
            "description": "Ids of supporting documents (uploaded files / e-mails) attached to this booking.",
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "businessCase": {
            "description": "Free-text business case label shown on the journal.",
            "type": "string",
            "example": "Office supplies"
          },
          "snippets": {
            "description": "Snippet identifiers applied to this booking, copied from the booking template.",
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "bookingStatus": {
            "description": "Status of the booking. Allowed values: DRAFT, BOOKED, CANCELLED.",
            "type": "string",
            "example": "BOOKED"
          },
          "internalComment": {
            "description": "Internal comment, visible only to accounting users.",
            "type": "string"
          },
          "businessCaseId": {
            "description": "Reference to the business-case document (workflow id) that produced this booking, when applicable.",
            "type": "string"
          },
          "relatedBookingHeaderLinks": {
            "description": "URIs of bookings that are related to this one (e.g. payment ↔ invoice, original ↔ delimitation).",
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "bookingDetails": {
            "description": "Debit and credit lines of the booking. Must contain at least two lines whose debit and credit totals balance.",
            "minItems": 2,
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PublicApiBookingDetail"
            },
            "nullable": false
          },
          "invoiceNumber": {
            "description": "Invoice number printed on the document.",
            "type": "string",
            "example": "2024-019"
          },
          "orderManagementInvoiceLink": {
            "description": "Klara order-management invoice URI when the booking was generated from a Klara invoice.",
            "type": "string"
          },
          "bookingTemplateId": {
            "format": "int64",
            "description": "Id of the booking template the user picked when creating this entry.",
            "type": "integer",
            "example": 501
          },
          "bookingTitle": {
            "description": "Short title of the booking shown in lists.",
            "type": "string",
            "example": "Office supplies — June 2024"
          },
          "totalAmount": {
            "description": "Sum of the absolute amounts of the booking lines, in the company main currency.",
            "type": "number",
            "example": 150
          },
          "bookingTypeCode": {
            "description": "Business meaning of the booking. Allowed values include GENERAL_LEDGER, AR_INVOICE, AP_INVOICE, AR_PAYMENT, AP_PAYMENT, AR_CREDIT_NOTE, AP_CREDIT_NOTE.",
            "type": "string",
            "example": "GENERAL_LEDGER"
          }
        }
      },
      "PublicApiBookingType": {
        "description": "A master booking type from Klara's global accounting catalog.",
        "type": "object",
        "properties": {
          "code": {
            "description": "Stable machine-readable code of the booking type.",
            "enum": [
              "GENERAL_LEDGER",
              "AP_INVOICE",
              "AP_PAYMENT",
              "AR_INVOICE",
              "AR_PAYMENT",
              "AP_PREPAYMENT",
              "AP_PREPAYUSE",
              "AR_PREPAYMENT",
              "AR_PREPAYUSE",
              "AR_CREDITNOTE",
              "AR_CREDITUSE",
              "AP_CREDITNOTE",
              "AP_CREDITUSE",
              "AMORTIZATION",
              "SELLOFF_AMORTIZATION",
              "DELIMIT"
            ],
            "type": "object",
            "example": "AP_INVOICE"
          },
          "description": {
            "description": "Localized human-readable description of the booking type. Resolved against the request's <code>Accept-Language</code> header; falls back to the German translation when no translation exists for the requested language.",
            "type": "string",
            "example": "Kreditorenrechnung"
          }
        }
      },
      "PublicApiBusinessCase": {
        "description": "Hydrated business-case aggregate: template, dates the company-VAT and fiscal year resolve to, and the snippet / field tree used by the booking form.",
        "type": "object",
        "properties": {
          "businessCaseId": {
            "format": "int64",
            "description": "Identifier of the business case instance when persisted; null on a freshly hydrated template.",
            "type": "integer",
            "example": "null"
          },
          "businessCaseTemplateId": {
            "format": "int64",
            "description": "Identifier of the business-case template this aggregate was hydrated from.",
            "type": "integer",
            "example": 101
          },
          "documentId": {
            "description": "Identifier of the underlying document the business case is attached to; null when the booking is not yet linked to a document.",
            "type": "string",
            "example": "null"
          },
          "display": {
            "description": "Pre-translated display label of the business-case template for the request's Accept-Language.",
            "type": "string",
            "example": "Bürobedarf"
          },
          "bookingNumbers": {
            "description": "Comma-separated list of booking numbers already generated for this business case; empty on a fresh template.",
            "type": "string",
            "example": ""
          },
          "effectiveCompanyVatDate": {
            "format": "date",
            "description": "Date used to resolve the company-VAT regime applicable to this business case (ISO yyyy-MM-dd).",
            "type": "string",
            "example": "2024-06-15"
          },
          "documentDate": {
            "format": "date",
            "description": "Document date associated with the business case (ISO yyyy-MM-dd).",
            "type": "string",
            "example": "2024-06-15"
          },
          "effectiveFiscalYearDate": {
            "format": "date",
            "description": "Date used to resolve the fiscal year applicable to this business case (ISO yyyy-MM-dd).",
            "type": "string",
            "example": "2024-06-15"
          },
          "fiscalYearHasCreatedAuto": {
            "description": "True when the downstream service had to auto-create the fiscal year covering the resolved date.",
            "type": "boolean",
            "example": false
          },
          "withOP": {
            "description": "True when this business case is tracked as an open item (OP). May be null when not applicable.",
            "type": "boolean",
            "example": false
          },
          "fields": {
            "description": "Recursive snippet-and-field tree driving the booking form, keyed by snippet code. The shape of each entry follows the downstream BusinessCaseField model (see analysis report §8.2).",
            "type": "object",
            "additionalProperties": {
              "type": "object"
            },
            "example": {
              "PAYMENT": {
                "snippetId": 42,
                "nestedFields": {}
              }
            }
          },
          "entriesDefinition": {
            "description": "Per-field entries definitions used by the booking form to resolve enum-like fields. Each entry mirrors the downstream FieldEntriesDefinition model (see analysis report §8.2).",
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": {
                "type": "object"
              }
            }
          }
        }
      },
      "PublicApiBusinessCasePeriod": {
        "description": "A financial-year period and the business-case templates valid for the company within it.",
        "type": "object",
        "properties": {
          "companyId": {
            "format": "int64",
            "description": "Internal id of the company this period belongs to.",
            "type": "integer",
            "example": 1
          },
          "periodFrom": {
            "format": "date",
            "description": "Inclusive start date of the financial year (ISO yyyy-MM-dd).",
            "type": "string",
            "example": "2024-01-01"
          },
          "periodTo": {
            "format": "date",
            "description": "Inclusive end date of the financial year (ISO yyyy-MM-dd).",
            "type": "string",
            "example": "2024-12-31"
          },
          "legalForm": {
            "description": "Legal form of the company during this period. Allowed values include EINZEL, GMBH, AG, KOLLEKTIV, KOMMANDIT, GENOSSENSCHAFT, VEREIN, STIFTUNG.",
            "type": "string",
            "example": "EINZEL"
          },
          "companyVat": {
            "allOf": [
              {
                "$ref": "#/components/schemas/PublicApiCompanyVatType"
              },
              {
                "description": "VAT regime active during this period."
              }
            ]
          },
          "status": {
            "description": "Status of the fiscal year. Allowed values: OPEN, CLOSING, CLOSED.",
            "type": "string",
            "example": "OPEN"
          },
          "businessCaseTemplates": {
            "description": "Business-case templates valid for the company's legal form and VAT regime within this period, sorted by code.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PublicApiBusinessCaseTemplate"
            }
          }
        }
      },
      "PublicApiBusinessCaseTemplate": {
        "description": "A manual-journal category usable for bookings, with its catalogue code and translations.",
        "type": "object",
        "properties": {
          "id": {
            "format": "int64",
            "description": "Internal id of the template in the Klara catalogue.",
            "type": "integer",
            "example": 101
          },
          "code": {
            "description": "Stable catalogue code of the template.",
            "type": "string",
            "example": "OFFICE_SUPPLIES"
          },
          "display": {
            "description": "Label of the template, already translated for the request's Accept-Language.",
            "type": "string",
            "example": "Bürobedarf"
          },
          "i18n": {
            "description": "All translations of the label, keyed by IETF language tag.",
            "type": "object",
            "additionalProperties": {
              "type": "string"
            },
            "example": {
              "de": "Bürobedarf",
              "fr": "Fournitures de bureau"
            }
          },
          "keywordI18ns": {
            "description": "All translations of the search keywords, keyed by IETF language tag.",
            "type": "object",
            "additionalProperties": {
              "type": "string"
            },
            "example": {
              "de": "Büro Material",
              "fr": "Fournitures"
            }
          },
          "group": {
            "description": "Catalogue group the template belongs to.",
            "type": "string",
            "example": "Operating expenses"
          }
        }
      },
      "PublicApiCompanyVatType": {
        "description": "VAT regime of a company within a fiscal period.",
        "type": "object",
        "properties": {
          "id": {
            "format": "int64",
            "description": "Internal id of the company VAT row.",
            "type": "integer",
            "example": 42
          },
          "reportingVat": {
            "description": "Reporting method used to declare VAT. Allowed values: EFFECTIVE, NET_TAX_RATE, FLAT_TAX_RATE.",
            "type": "string",
            "example": "EFFECTIVE"
          },
          "billing": {
            "description": "Billing method used to determine VAT liability. Allowed values: AGREED, RECEIVED.",
            "type": "string",
            "example": "AGREED"
          },
          "code": {
            "description": "Composite VAT code combining reporting method and billing, or NON_VAT when the company is not VAT-liable.",
            "type": "string",
            "example": "EFFECTIVE_AGREED"
          },
          "hasVat": {
            "description": "True when the company is VAT-liable in this period.",
            "type": "boolean",
            "example": true
          },
          "validFrom": {
            "format": "date",
            "description": "Inclusive start date of the VAT regime (ISO yyyy-MM-dd).",
            "type": "string",
            "example": "2024-01-01"
          },
          "validTo": {
            "format": "date",
            "description": "Inclusive end date of the VAT regime (ISO yyyy-MM-dd).",
            "type": "string",
            "example": "2024-12-31"
          },
          "yearlySettlement": {
            "description": "True for yearly VAT settlement, false for quarterly/semi-annual.",
            "type": "boolean",
            "example": false
          }
        }
      },
      "PublicApiCrDrType": {
        "enum": [
          "CR",
          "DR"
        ],
        "type": "string"
      },
      "PublicApiEmployeeShortInfo": {
        "description": "Lightweight employee entry (identity, contact and workplace) for directory/lookup listings.",
        "type": "object",
        "properties": {
          "id": {
            "format": "int64",
            "description": "Employee id. Use this as employeeId in employee-scoped endpoints.",
            "type": "integer",
            "example": 3487
          },
          "firstName": {
            "description": "Employee's first name (resolved from the person record).",
            "type": "string",
            "example": "Anna"
          },
          "lastName": {
            "description": "Employee's last name (resolved from the person record).",
            "type": "string",
            "example": "Müller"
          },
          "employeeNumber": {
            "description": "Company-assigned employee number.",
            "type": "string",
            "example": "E-00123"
          },
          "email": {
            "description": "Employee's primary email (resolved from the person record).",
            "type": "string",
            "example": "anna.mueller@example.com"
          },
          "workplaceId": {
            "format": "int64",
            "description": "Id of the workplace of the employee's current contract.",
            "type": "integer",
            "example": 12
          },
          "personnelNumber": {
            "description": "Personnel number of the employee.",
            "type": "string",
            "example": "P-4711"
          },
          "numberOfChildren": {
            "format": "int64",
            "description": "Number of children registered for the employee.",
            "type": "integer",
            "example": 2
          },
          "cashPayment": {
            "description": "Whether the employee is paid in cash.",
            "type": "boolean",
            "example": false
          },
          "status": {
            "description": "Contract status of the employee. Allowed values: ACTIVE, INACTIVE, DRAFT.",
            "type": "string",
            "example": "ACTIVE"
          }
        }
      },
      "PublicApiFailArticle": {
        "description": "Contain error information and data of unsaved article",
        "type": "object",
        "properties": {
          "errorCode": {
            "description": "Error code",
            "type": "string",
            "example": "article.number.could.not.be.duplicated"
          },
          "errorMessage": {
            "description": "Error message",
            "type": "string",
            "example": "Article number could not be duplicated"
          },
          "unsavedArticle": {
            "allOf": [
              {
                "$ref": "#/components/schemas/Article"
              },
              {
                "description": "Article data which could not be saved"
              }
            ]
          }
        }
      },
      "PublicApiFieldEntry": {
        "description": "One concrete sub-account choice; carries the URI to round-trip to the booking endpoint and the display label.",
        "type": "object",
        "properties": {
          "id": {
            "description": "Stable identifier of the underlying entity (e.g. bank-account id, VAT-rate id, customer id). May be <code>null</code> for synthesized entries.",
            "type": "string",
            "example": "42"
          },
          "filteredBy": {
            "description": "Optional filter token used by the Accounting UI to narrow the picker. Empty for most link types.",
            "type": "string",
            "example": ""
          },
          "display": {
            "description": "Human-readable label shown in the picker (e.g. <code>\"UBS\"</code> for a bank account, <code>\"8.1 %\"</code> for a VAT rate).",
            "type": "string",
            "example": "UBS"
          },
          "link": {
            "description": "Canonical URI for this sub-account choice. MUST be round-tripped verbatim to the booking-creation endpoint when the row is selected.",
            "type": "string",
            "example": "bank_account:/luz_finance/api/5fe76717-60a0-4b20-9819-255a957f3eb9/companies/1/bank-accounts/42"
          },
          "additionalAttribute": {
            "description": "Free-form additional attribute attached by the link-type supplier. Most types leave this empty.",
            "type": "string",
            "example": ""
          },
          "snippetReference": {
            "description": "Optional snippet reference returned by the underlying entity (used by some link types to carry a template hint).",
            "type": "string",
            "example": ""
          },
          "value": {
            "description": "Optional raw value associated with the entry (e.g. the VAT percentage as a decimal string).",
            "type": "string",
            "example": "8.1"
          },
          "validFrom": {
            "format": "date",
            "description": "Inclusive start of the validity window of the underlying entity (ISO <code>yyyy-MM-dd</code>). <code>null</code> when not applicable.",
            "type": "string",
            "example": "2024-01-01"
          },
          "validTo": {
            "format": "date",
            "description": "Inclusive end of the validity window of the underlying entity (ISO <code>yyyy-MM-dd</code>). <code>null</code> when open-ended.",
            "type": "string",
            "example": "2024-12-31"
          }
        }
      },
      "PublicApiMasterVat": {
        "description": "Global master VAT row: code, rate, validity range and translated labels.",
        "type": "object",
        "properties": {
          "id": {
            "format": "int64",
            "description": "Internal id of the master VAT row.",
            "type": "integer",
            "example": 12
          },
          "vatCode": {
            "description": "Short numeric VAT code as configured in the Klara accounting plan.",
            "type": "string",
            "example": "1"
          },
          "rate": {
            "description": "VAT rate as a percentage value (8.10 means 8.10 %).",
            "type": "number",
            "example": 8.1
          },
          "validFrom": {
            "format": "date",
            "description": "Inclusive start date of the validity range (ISO yyyy-MM-dd). May be null when open-ended.",
            "type": "string",
            "example": "2024-01-01"
          },
          "validTo": {
            "format": "date",
            "description": "Inclusive end date of the validity range (ISO yyyy-MM-dd). May be null when open-ended.",
            "type": "string",
            "example": "2030-12-31"
          },
          "defaultVat": {
            "description": "True when the row is one of the company-default VAT entries.",
            "type": "boolean",
            "example": true
          },
          "masterVatMulties": {
            "description": "Localized labels keyed by language tag.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PublicApiMasterVatMulti"
            }
          },
          "referenceVatCaseId": {
            "description": "Optional reference to a hidden VAT case id not directly mapped to a master VAT.",
            "type": "string",
            "example": "VC-7"
          },
          "createDate": {
            "format": "date-time",
            "description": "Timestamp when the row was created (ISO yyyy-MM-dd'T'HH:mm:ss).",
            "type": "string",
            "example": "2024-01-01T08:00:00"
          },
          "updateDate": {
            "format": "date-time",
            "description": "Timestamp of the last update (ISO yyyy-MM-dd'T'HH:mm:ss).",
            "type": "string",
            "example": "2024-06-15T14:30:00"
          }
        }
      },
      "PublicApiMasterVatMulti": {
        "description": "Translated label of a master VAT row.",
        "type": "object",
        "properties": {
          "id": {
            "format": "int64",
            "description": "Internal id of the translation row.",
            "type": "integer",
            "example": 101
          },
          "language": {
            "description": "Language tag of the translation (ISO 639-1).",
            "type": "string",
            "example": "de"
          },
          "description": {
            "description": "Human-readable VAT description in the matching language.",
            "type": "string",
            "example": "Normalsatz 8.1 %"
          }
        }
      },
      "PublicApiSuitableOpenPosition": {
        "description": "An accounting open-position booking detail line returned by the bank-reconciliation suggestion service. Carries the canonical booking-detail fields plus reconciliation-specific enrichments (partner-name display, business-case message id, computed open amount).",
        "type": "object",
        "properties": {
          "id": {
            "format": "int64",
            "description": "Booking-detail row id (database primary key).",
            "type": "integer",
            "example": 98765
          },
          "bookingHeaderId": {
            "format": "int64",
            "description": "Id of the booking header this detail belongs to.",
            "type": "integer",
            "example": 4321
          },
          "bookingHeaderComment": {
            "description": "Free-text comment of the booking header.",
            "type": "string",
            "example": "Invoice 2026-0123 from Migros AG"
          },
          "businessCaseId": {
            "format": "int64",
            "description": "Id of the parent business case.",
            "type": "integer",
            "example": 12345
          },
          "accountCode": {
            "description": "Numeric account code on which the booking is posted.",
            "type": "string",
            "example": "1100"
          },
          "accountLinkDisplay": {
            "description": "Localized account label.",
            "type": "string",
            "example": "Forderungen aus L+L"
          },
          "crdrType": {
            "description": "Credit / debit indicator.",
            "enum": [
              "CR",
              "DR"
            ],
            "type": "object",
            "example": "DR"
          },
          "description": {
            "description": "Free-text description of the booking line.",
            "type": "string",
            "example": "Rechnung Nr. 2026-0123"
          },
          "bookingTypeCode": {
            "description": "Stable booking-type code of the underlying business case.",
            "enum": [
              "GENERAL_LEDGER",
              "AP_INVOICE",
              "AP_PAYMENT",
              "AR_INVOICE",
              "AR_PAYMENT",
              "AP_PREPAYMENT",
              "AP_PREPAYUSE",
              "AR_PREPAYMENT",
              "AR_PREPAYUSE",
              "AR_CREDITNOTE",
              "AR_CREDITUSE",
              "AP_CREDITNOTE",
              "AP_CREDITUSE",
              "AMORTIZATION",
              "SELLOFF_AMORTIZATION",
              "DELIMIT"
            ],
            "type": "object",
            "example": "AR_INVOICE"
          },
          "openPositionStatus": {
            "description": "Open-position lifecycle status.",
            "enum": [
              "OPEN",
              "PARTLY_PAID",
              "PAID",
              "PARTLY_CLEARED",
              "CLEARED"
            ],
            "type": "object",
            "example": "OPEN"
          },
          "amount": {
            "description": "Gross posted amount of the booking line.",
            "type": "number",
            "example": 1250
          },
          "partialPaymentAmount": {
            "description": "Sum of payments / clearings already applied to this position.",
            "type": "number",
            "example": 0
          },
          "openAmount": {
            "description": "Computed remaining amount still to be cleared (<code>amount - partialPaymentAmount</code>).",
            "type": "number",
            "example": 1250
          },
          "vatAmount": {
            "description": "VAT amount included in the gross posting.",
            "type": "number",
            "example": 94.05
          },
          "vatRate": {
            "description": "VAT rate applied to the line as a decimal (e.g. <code>0.077</code>).",
            "type": "number",
            "example": 0.081
          },
          "vatRateDisplay": {
            "description": "Localized VAT-rate display string.",
            "type": "string",
            "example": "8.1 %"
          },
          "vatBookingDetailLink": {
            "description": "Self-link of the companion VAT booking-detail line, when present.",
            "type": "string"
          },
          "vatBookingDetail": {
            "description": "Whether this row is itself a derived VAT booking-detail line.",
            "type": "boolean",
            "example": false
          },
          "foreignCurrencyAmount": {
            "description": "Posted amount in the document's foreign currency, when applicable.",
            "type": "number",
            "example": 1250
          },
          "foreignCurrencyUnit": {
            "description": "ISO-4217 currency code of <code>foreignCurrencyAmount</code>.",
            "type": "string",
            "example": "EUR"
          },
          "tags": {
            "description": "Free-form tag string attached to the booking line.",
            "type": "string",
            "example": "test manual"
          },
          "documentDate": {
            "format": "date",
            "description": "Document (invoice) date of the underlying business case.",
            "type": "string",
            "example": "2026-04-15"
          },
          "bookingDate": {
            "format": "date",
            "description": "Date the booking was journaled.",
            "type": "string",
            "example": "2026-04-15"
          },
          "paidDate": {
            "format": "date",
            "description": "Date the position was last (partially) paid, if any.",
            "type": "string",
            "example": "2026-05-10"
          },
          "dueDate": {
            "format": "date",
            "description": "Due date for payment.",
            "type": "string",
            "example": "2026-05-15"
          },
          "paymentDate": {
            "format": "date",
            "description": "Effective payment date of the booking line.",
            "type": "string",
            "example": "2026-05-12"
          },
          "servicePeriodFrom": {
            "format": "date",
            "description": "Inclusive lower bound of the service period this booking covers.",
            "type": "string",
            "example": "2026-04-01"
          },
          "servicePeriodTo": {
            "format": "date",
            "description": "Inclusive upper bound of the service period this booking covers.",
            "type": "string",
            "example": "2026-04-30"
          },
          "createDate": {
            "format": "date-time",
            "description": "Timestamp at which the booking detail was created.",
            "type": "string",
            "example": "2026-04-15T08:30:00"
          },
          "updateDate": {
            "format": "date-time",
            "description": "Timestamp at which the booking detail was last updated.",
            "type": "string",
            "example": "2026-05-12T14:15:00"
          },
          "documentId": {
            "description": "List of document ids attached to the booking line.",
            "type": "array",
            "items": {
              "type": "string"
            },
            "example": [
              "1771764"
            ]
          },
          "partnerName": {
            "description": "Resolved partner display name for the position.",
            "type": "string",
            "example": "Migros AG"
          },
          "bookingDetailUri": {
            "description": "Stable URI of the booking-detail row, for cross-service linking.",
            "type": "string",
            "example": "/api/luz_accounting/api/{tenantId}/companies/{companyId}/booking-headers/4321/booking-details/98765"
          },
          "orderManagementInvoiceLink": {
            "description": "Self-link of the linked order-management invoice, when applicable.",
            "type": "string"
          },
          "orderManagementInvoiceNumber": {
            "description": "Resolved order-management invoice number for display.",
            "type": "string",
            "example": "INV-2026-0123"
          },
          "msgId": {
            "description": "Business-case message id, used by the eletter / inbox subsystems.",
            "type": "string",
            "example": "MSG-7788"
          },
          "creditorReference": {
            "description": "Creditor reference (Swiss QR-IBAN reference number) of the position.",
            "type": "string"
          },
          "isrReference": {
            "description": "ISR reference of the position, when applicable.",
            "type": "string"
          },
          "isrMember": {
            "description": "ISR member number, when applicable.",
            "type": "string"
          },
          "partnerIban": {
            "description": "IBAN of the partner / counterparty.",
            "type": "string"
          },
          "endToEndId": {
            "description": "End-to-end identifier carried on the bank transaction.",
            "type": "string"
          }
        }
      },
      "PublicApiVatProfile": {
        "description": "The company's VAT reporting profile.",
        "type": "object",
        "properties": {
          "hasVat": {
            "description": "Whether the company is VAT-registered.",
            "type": "boolean",
            "example": true
          },
          "reportingMode": {
            "description": "VAT regime. EFFECTIVE_CLEARING or REPORTING_USING_NET_TAX_RATES.",
            "type": "string",
            "example": "EFFECTIVE_CLEARING"
          },
          "billing": {
            "description": "Billing method. BILLED or COLLECTED.",
            "type": "string",
            "example": "BILLED"
          },
          "sss1": {
            "description": "Flat net-tax rate 1 (percent), when reporting under net tax rates.",
            "type": "number",
            "example": 1
          },
          "sss2": {
            "description": "Flat net-tax rate 2 (percent), when reporting under net tax rates.",
            "type": "number",
            "example": 0.5
          }
        }
      },
      "PublicApiVatSuggestion": {
        "description": "A ready-to-use VAT case/rate/account bundle.",
        "type": "object",
        "properties": {
          "label": {
            "description": "Human-meaningful label. Use it as the option text in the VAT-rate dropdown.",
            "type": "string",
            "example": "Domestic purchase — 8.1%"
          },
          "recommended": {
            "description": "True on the server's recommended default bundle — preselect this row in the dropdowns.",
            "type": "boolean",
            "example": true
          },
          "reason": {
            "description": "Why this bundle is suggested.",
            "type": "string",
            "example": "Default VAT rate for DOMESTIC_PURCHASE."
          },
          "vatCaseCode": {
            "description": "VAT case code. Group rows by this value to build the VAT-case dropdown.",
            "type": "string",
            "example": "DOMESTIC_PURCHASE"
          },
          "vatCaseLink": {
            "description": "Verbatim link to copy into a booking line's links (comma-joined with vatRateLink).",
            "type": "string",
            "example": "vat_case:/luz_accounting/api/vat-cases/1"
          },
          "vatRateDisplay": {
            "description": "Display string of the VAT rate — the VAT-rate dropdown option within the selected VAT case.",
            "type": "string",
            "example": "8.1%"
          },
          "vatRateLink": {
            "description": "Verbatim link to copy into a booking line's links (comma-joined with vatCaseLink).",
            "type": "string",
            "example": "vat_rate:/luz_accounting/api/master-vats/59"
          },
          "vatAccountCode": {
            "format": "int32",
            "description": "Suggested VAT account for the generated VAT line — preselect this in the VAT-account dropdown; the first of vatAccountCodes (confirm against your chart of accounts).",
            "type": "integer",
            "example": 1170
          },
          "vatAccountCodes": {
            "description": "All VAT accounts the company's chart maps to this account + VAT case; the options for the GUI's VAT-account dropdown.",
            "type": "array",
            "items": {
              "format": "int32",
              "type": "integer"
            },
            "example": [
              1170,
              1171
            ]
          },
          "previewNet": {
            "description": "Net amount preview — the Debit/Credit preview shown in the GUI. Null until an amount is supplied; refreshes when amount/amountKind change.",
            "type": "number",
            "example": 925.93
          },
          "previewVat": {
            "description": "VAT amount preview — the VAT portion shown in the GUI. Null until an amount is supplied; refreshes when amount/amountKind change.",
            "type": "number",
            "example": 74.07
          }
        }
      },
      "PublicApiVatType": {
        "description": "A VAT-type row from Klara's global VAT-type catalogue.",
        "type": "object",
        "properties": {
          "vatTypeCode": {
            "description": "Klara VAT-type code that identifies the row.",
            "type": "string",
            "example": "M81"
          },
          "companyType": {
            "description": "Company-type bucket the VAT type applies to.",
            "type": "string",
            "example": "LIMITED_LIABILITY"
          },
          "description": {
            "description": "Localized description, resolved against the request <code>Accept-Language</code> header (German fallback).",
            "type": "string",
            "example": "Vorsteuer Material- und Dienstleistungsaufwand"
          },
          "vatTypeShortName": {
            "description": "Localized short name, resolved against the request <code>Accept-Language</code> header (German fallback).",
            "type": "string",
            "example": "VSt MA"
          },
          "i18n": {
            "description": "Raw description translations keyed by lowercase IETF language tag. Useful when a client renders its own language picker; otherwise prefer the resolved <code>description</code> field.",
            "type": "object",
            "additionalProperties": {
              "type": "string"
            }
          },
          "i18nShortName": {
            "description": "Raw short-name translations keyed by lowercase IETF language tag.",
            "type": "object",
            "additionalProperties": {
              "type": "string"
            }
          },
          "vatTypeFormula": {
            "description": "Posting formulas attached to this VAT type, one per associated VAT case.",
            "uniqueItems": true,
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PublicApiVatTypeFormula"
            }
          }
        }
      },
      "PublicApiVatTypeFormula": {
        "description": "Posting formula attached to a Klara VAT type.",
        "type": "object",
        "properties": {
          "vatCaseCode": {
            "description": "Linked VAT-case code this formula belongs to.",
            "type": "string",
            "example": "VAT_RECEIVABLE"
          },
          "vatTypeCode": {
            "description": "VAT-type code this formula belongs to.",
            "type": "string",
            "example": "M81"
          },
          "companyType": {
            "description": "Company-type bucket the formula applies to.",
            "type": "string",
            "example": "LIMITED_LIABILITY"
          },
          "account": {
            "description": "Account number on which the VAT entry is booked.",
            "type": "string",
            "example": "2200"
          },
          "contraAccount": {
            "description": "Contra-account number for the VAT entry.",
            "type": "string",
            "example": "1170"
          },
          "linkedBookingAccount": {
            "description": "Linked auxiliary account, when applicable.",
            "type": "string",
            "example": "2201"
          },
          "specialRatesType": {
            "description": "Special-rates flag (enum name from the upstream model). Surfaced as a string so future internal enum additions stay backwards compatible.",
            "type": "string",
            "example": "STANDARD"
          },
          "value": {
            "description": "Formula value flag (enum name from the upstream model). Surfaced as a string for forward compatibility.",
            "type": "string",
            "example": "NORMAL"
          }
        }
      },
      "RepresentationLinks": {
        "description": "links metadata",
        "type": "object",
        "properties": {
          "self": {
            "$ref": "#/components/schemas/Link"
          }
        }
      },
      "Salutation": {
        "enum": [
          "MALE",
          "FEMALE",
          "MALE_FEMALE",
          "FAMILY"
        ],
        "type": "string"
      },
      "SendInvoiceResult": {
        "description": "Result of sending a single, already-booked invoice. Reports whether the invoice was delivered, whether the channel was auto-selected (smart delivery), the channel actually used, the OneAPI delivery id and the archived PDF's printedFileId.",
        "type": "object",
        "properties": {
          "delivered": {
            "description": "<code>true</code> when delivery was confirmed via the channel actually used.",
            "type": "boolean",
            "example": true
          },
          "smart": {
            "description": "<code>true</code> when the channel was auto-selected (smart delivery, i.e. no <code>channel</code> was forced); <code>false</code> when a channel was forced.",
            "type": "boolean",
            "example": true
          },
          "channel": {
            "description": "The channel actually used to deliver the invoice. For physical post this is the resolved postage method (e.g. <code>A_POST</code>).",
            "enum": [
              "A_POST",
              "B_POST",
              "SEND_EMAIL",
              "PRINT_AND_MANUAL_SEND",
              "EPOST",
              "EBILL"
            ],
            "type": "object",
            "example": "SEND_EMAIL"
          },
          "deliveryId": {
            "description": "OneAPI delivery id, when available (forced sends only; <code>null</code> for smart delivery).",
            "type": "string",
            "example": "9b1f4c8e-2d3a-4f6b-8c7d-1e2f3a4b5c6d"
          },
          "printedFileId": {
            "description": "The printedFileId of the archived invoice PDF rendered/reused during the send.",
            "type": "string",
            "example": "1771764"
          }
        }
      },
      "ShippingInfo": {
        "description": "shipping information for an article.",
        "type": "object",
        "properties": {
          "shippingAttributes": {
            "description": "List of attributes used for shipping",
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "weightUnit": {
            "$ref": "#/components/schemas/WeightUnit"
          },
          "dimensionUnit": {
            "$ref": "#/components/schemas/DimensionUnit"
          },
          "weight": {
            "description": "Weight of this article",
            "pattern": "^\\d{1,19}([.]\\d{1,2})?$",
            "type": "number"
          },
          "width": {
            "description": "Width of this article",
            "pattern": "^\\d{1,19}([.]\\d{1,2})?$",
            "type": "number"
          },
          "height": {
            "description": "Height of this article",
            "pattern": "^\\d{1,19}([.]\\d{1,2})?$",
            "type": "number"
          },
          "depth": {
            "description": "Depth of this article",
            "pattern": "^\\d{1,19}([.]\\d{1,2})?$",
            "type": "number"
          }
        }
      },
      "SortDirection": {
        "description": "Sort direction. Allowed values: ASC, DESC.",
        "enum": [
          "ASC",
          "DESC"
        ],
        "type": "string"
      },
      "State": {
        "description": "A partner State.",
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "readOnly": true
          },
          "code": {
            "description": "Code of this State",
            "type": "string",
            "example": "VD"
          },
          "description": {
            "description": "Extended description of this State",
            "type": "string",
            "example": "Vaud"
          }
        }
      },
      "Subscription": {
        "description": "Subscription for a product in KLARA. Enable different features for users.",
        "required": [
          "product",
          "marketingCodes"
        ],
        "type": "object",
        "properties": {
          "product": {
            "allOf": [
              {
                "$ref": "#/components/schemas/Product"
              },
              {
                "description": "The product to be subscribed. Identifier code for each product-should be unique across all products.",
                "nullable": false
              }
            ]
          },
          "marketingCodes": {
            "description": "Marketing code to identify which product will be subscribed.",
            "type": "array",
            "items": {
              "type": "string"
            },
            "example": "K-01-0002-00-M, K-02-0005-00-Y",
            "nullable": false
          },
          "pricePlan": {
            "allOf": [
              {
                "$ref": "#/components/schemas/PricePlan"
              },
              {
                "description": "Specify how the subscription is paid. <br><ul><li> SINGLE: Pay once for the whole subscription period. </li><li> VOLUME: Pay once for the whole subscription period and pay for each volume. </li><li> MONTHLY: Pay monthly for the subscription period. </li><li> QUARTERLY: Pay quarterly for the subscription period. </li><li> YEARLY: Pay yearly for the subscription period. </li><li> FREE: Free subscription. </li><li> PAY_PER_USE: Pay for each usage. </li></ul>",
                "enum": [
                  "SINGLE",
                  "VOLUME",
                  "MONTHLY",
                  "QUARTERLY",
                  "YEARLY",
                  "FREE",
                  "PAY_PER_USE"
                ],
                "example": "MONTHLY"
              }
            ]
          },
          "price": {
            "description": "The price of this subscription at this moment",
            "type": "number",
            "readOnly": true,
            "example": 10
          },
          "subscriptionFrom": {
            "format": "date-time",
            "description": "Specify when the subscription will start effectively. By default, the start date is today",
            "type": "string",
            "example": "2023-11-20 T10:15:30"
          },
          "subscriptionUntil": {
            "format": "date-time",
            "description": "Specify when the subscription will end effectively after unsubscribe. This value will be calculated by service itself.",
            "type": "string",
            "readOnly": true,
            "example": "2024-11-20 T10:15:30"
          },
          "renewalDate": {
            "format": "date",
            "description": "Indicates the date that subscription will automatically renewed for another period if no cancellation is made before this date.",
            "type": "string",
            "example": "2024-20-11"
          }
        }
      },
      "SwissBank": {
        "type": "object",
        "properties": {
          "id": {
            "format": "int64",
            "description": "Internal Swiss-bank master-data id.",
            "type": "integer",
            "example": 100
          },
          "group": {
            "description": "Master-data group code.",
            "type": "string",
            "example": "1"
          },
          "bankClearingNumber": {
            "description": "Bank clearing number (BCNR).",
            "type": "string",
            "example": "100"
          },
          "branchId": {
            "description": "Branch identifier.",
            "type": "string",
            "example": "1"
          },
          "newBankClearingNumber": {
            "description": "Successor BCNR if the bank has been replaced.",
            "type": "string",
            "example": ""
          },
          "sicNumber": {
            "description": "SIC member number.",
            "type": "string",
            "example": "100000"
          },
          "headOfficeNumber": {
            "description": "Head-office BCNR.",
            "type": "string",
            "example": "100"
          },
          "bankClearingType": {
            "description": "Bank-clearing classification code.",
            "type": "string",
            "example": "1"
          },
          "euroSic": {
            "description": "SIC participation in EUR.",
            "type": "string",
            "example": ""
          },
          "language": {
            "description": "Master-data language code.",
            "type": "string",
            "example": "de"
          },
          "shortName": {
            "description": "Bank short name.",
            "type": "string",
            "example": "PostFinance AG"
          },
          "name": {
            "description": "Bank legal name.",
            "type": "string",
            "example": "PostFinance AG"
          },
          "address": {
            "description": "Bank street address.",
            "type": "string",
            "example": "Mingerstrasse 20"
          },
          "postalAddress": {
            "description": "Postal address (PO Box).",
            "type": "string",
            "example": "Postfach"
          },
          "place": {
            "description": "City / locality.",
            "type": "string",
            "example": "Bern"
          },
          "phone": {
            "description": "Bank phone number.",
            "type": "string",
            "example": "+41 58 338 25 00"
          },
          "fax": {
            "description": "Bank fax number.",
            "type": "string",
            "example": ""
          },
          "dailingCode": {
            "description": "International dialling code.",
            "type": "string",
            "example": "41"
          }
        }
      },
      "Tenant": {
        "description": "A Company Tenant.",
        "type": "object",
        "properties": {
          "tenant_id": {
            "type": "string",
            "example": "aaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee"
          },
          "company_id": {
            "format": "int64",
            "type": "integer",
            "example": 1
          },
          "company_name": {
            "type": "string",
            "example": "ABC Company"
          }
        }
      },
      "VAT": {
        "description": "A VAT",
        "type": "object",
        "properties": {
          "id": {
            "description": "Id of the VAT.",
            "type": "string",
            "example": "1"
          },
          "vatCode": {
            "description": "Code of the VAT.",
            "type": "string",
            "example": "ABC"
          },
          "rate": {
            "description": "Rate of the VAT. Rate unit is percentage (%)",
            "type": "number",
            "example": 5
          },
          "description": {
            "description": "The additional infomation for VAT.",
            "type": "string",
            "example": "VAT's description"
          },
          "validFrom": {
            "format": "date",
            "description": "The VAT is valid from this time.",
            "type": "string"
          },
          "validTo": {
            "format": "date",
            "description": "The VAT is invalid after this time.",
            "type": "string"
          }
        }
      },
      "Variant": {
        "description": "An article variant.",
        "required": [
          "number",
          "accountingTags"
        ],
        "type": "object",
        "properties": {
          "id": {
            "description": "Id of the variant",
            "type": "string",
            "example": "1"
          },
          "number": {
            "description": "Article number",
            "type": "string",
            "example": "ABC123"
          },
          "barcode": {
            "description": "Barcode for the variant",
            "default": "",
            "type": "string"
          },
          "accountingTags": {
            "description": "Tags used for accounting. Articles with the same tag, same VAT case and same VAT rate are grouped together in the posting",
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "articleSets": {
            "description": "Name of the article sets that the variant is included in",
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "defaultQuantity": {
            "description": "The default quantity of the article",
            "type": "number"
          },
          "active": {
            "description": "Decide if this variant is active or not",
            "default": "false",
            "type": "boolean"
          },
          "pricePeriods": {
            "description": "Price periods for the article variant.<br />If variant only has 1 price, don't include validFrom and validTo in the PricePeriod.<br />If variant have many prices, set value for validFrom for the date that the price is active for each PricePeriod.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PricePeriod"
            }
          },
          "variantOptionValues": {
            "description": "Values for the options that this article variant represent",
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        }
      },
      "VatCase": {
        "description": "A Vat case.",
        "type": "object",
        "properties": {
          "id": {
            "description": "Id of the VAT Case.",
            "type": "string",
            "example": "1"
          },
          "vatCaseCode": {
            "description": "Code of the VAT Case.",
            "type": "string",
            "example": "ABC"
          },
          "description": {
            "description": "The additional infomation for VAT.",
            "type": "string",
            "example": "VAT Case's description"
          },
          "referenceMasterVat": {
            "description": "The reference master for VAT.",
            "type": "string"
          },
          "vatCaseNames": {
            "description": "The map contain VAT case names in many languages.",
            "type": "object",
            "additionalProperties": {
              "type": "string"
            }
          },
          "applicability": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ApplicabilityVatCaseType"
              },
              {
                "description": "The VAT case type.",
                "example": "REVENUE"
              }
            ]
          },
          "orderNumber": {
            "format": "int32",
            "description": "This value present how this VAT case order in the list as sequence.",
            "type": "integer",
            "example": 2
          },
          "createDate": {
            "format": "date-time",
            "description": "The date that VAT Case created.",
            "type": "string"
          },
          "updateDate": {
            "format": "date-time",
            "description": "The date that VAT Case updated.",
            "type": "string"
          }
        }
      },
      "VatClearingReport": {
        "description": "VAT clearing report of a company for a given reporting period.",
        "type": "object",
        "properties": {
          "id": {
            "format": "int64",
            "description": "Internal id of the report.",
            "type": "integer",
            "example": 987
          },
          "codeBoxes": {
            "description": "Code boxes that compose the VAT statement.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/VatClearingReportCodeBox"
            }
          },
          "status": {
            "allOf": [
              {
                "$ref": "#/components/schemas/VatClearingReportStatus"
              },
              {
                "description": "Current status of the report.",
                "example": "CALCULATED"
              }
            ]
          },
          "year": {
            "format": "int32",
            "description": "Calendar year of the reporting period.",
            "type": "integer",
            "example": 2024
          },
          "period": {
            "allOf": [
              {
                "$ref": "#/components/schemas/PeriodOfYear"
              },
              {
                "description": "Reporting period within the year.",
                "example": "Q1"
              }
            ]
          },
          "correctionCount": {
            "format": "int32",
            "description": "Number of booking corrections detected versus the sealed snapshot.",
            "type": "integer",
            "example": 0
          },
          "formerVatRateReleaseDate": {
            "format": "date",
            "description": "Release date of the former VAT rates that still apply to a part of the period.",
            "type": "string",
            "example": "2023-12-31T00:00:00Z"
          },
          "newVatRatesReleased": {
            "description": "Whether new VAT rates have been released and apply to part of the period.",
            "type": "boolean",
            "example": false
          },
          "periodFrom": {
            "format": "date",
            "description": "Start date of the reporting period.",
            "type": "string",
            "example": "2024-01-01T00:00:00Z"
          },
          "periodTo": {
            "format": "date",
            "description": "End date of the reporting period.",
            "type": "string",
            "example": "2024-03-31T00:00:00Z"
          }
        }
      },
      "VatClearingReportCodeBox": {
        "description": "Single code box of a VAT clearing report.",
        "type": "object",
        "properties": {
          "id": {
            "format": "int64",
            "description": "Internal id of the code box.",
            "type": "integer",
            "example": 1234
          },
          "code": {
            "description": "Code of the box on the VAT statement.",
            "type": "string",
            "example": "302"
          },
          "value": {
            "description": "Computed amount of the box.",
            "type": "number",
            "example": 12345.67
          },
          "description": {
            "description": "Localized description of the box.",
            "type": "string",
            "example": "Steuerbarer Umsatz"
          },
          "editable": {
            "description": "Whether the value of this box is editable by the user.",
            "type": "boolean",
            "example": false
          },
          "editableDescription": {
            "description": "Whether the description of this box is editable by the user.",
            "type": "boolean",
            "example": true
          },
          "rate": {
            "description": "VAT rate applied to this code box, in percent.",
            "type": "number",
            "example": 8.1
          }
        }
      },
      "VatClearingReportStatus": {
        "description": "Current status of a VAT clearing report.",
        "enum": [
          "CALCULATED",
          "SEALED"
        ],
        "type": "string",
        "example": "CALCULATED"
      },
      "WeightUnit": {
        "description": "Weight unit used for shipping of the article",
        "enum": [
          "GRAM",
          "KILOGRAM"
        ],
        "type": "string"
      }
    },
    "securitySchemes": {
      "apiKeyAuth": {
        "type": "apiKey",
        "name": "X-API-KEY",
        "in": "header"
      },
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "JWT"
      }
    }
  }
}
