{
  "openapi": "3.1.0",
  "paths": {
    "/api/v1/imports": {
      "get": {
        "description": "The firm’s latest imports, newest first, with how far each has got.\n\nScopes: `clients:read`. Part of the `hub` product: the firm must have it and you must have access to it.",
        "operationId": "Imports_list",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ImportBatchList"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "clients:read"
            ]
          }
        ],
        "summary": "List imports",
        "tags": [
          "Imports"
        ],
        "x-required-scopes": [
          "clients:read"
        ],
        "x-required-product": "hub"
      },
      "post": {
        "description": "Records the file and returns where to PUT it. A signed-in manager, partner or firm admin, never an API credential or assistant: a person always confirms what comes in.\n\nNeeds the Manager role or above. Part of the `hub` product: the firm must have it and you must have access to it. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "Imports_create",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateImportRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ImportCreated"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Start an import",
        "tags": [
          "Imports"
        ],
        "x-required-role": "manager",
        "x-required-product": "hub",
        "x-session-only": true
      }
    },
    "/api/v1/imports/kinds": {
      "get": {
        "description": "Each kind of import, its fields, the file types and limits, and whether you can use it.\n\nScopes: `clients:read`. Part of the `hub` product: the firm must have it and you must have access to it.",
        "operationId": "Imports_kinds",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ImportKindList"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "clients:read"
            ]
          }
        ],
        "summary": "List what can be imported",
        "tags": [
          "Imports"
        ],
        "x-required-scopes": [
          "clients:read"
        ],
        "x-required-product": "hub"
      }
    },
    "/api/v1/imports/templates/{kind}": {
      "get": {
        "description": "A spreadsheet with the headings Tolvi reads first and worked examples to overwrite.\n\nScopes: `clients:read`. Part of the `hub` product: the firm must have it and you must have access to it.",
        "operationId": "Imports_template",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "kind",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "enum": [
                "clients",
                "trial_balance",
                "ct_opening",
                "sa_prior_year"
              ]
            }
          },
          {
            "name": "format",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "xlsx",
                "csv"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A spreadsheet.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "clients:read"
            ]
          }
        ],
        "summary": "Download a template",
        "tags": [
          "Imports"
        ],
        "x-required-scopes": [
          "clients:read"
        ],
        "x-required-product": "hub"
      }
    },
    "/api/v1/imports/{id}": {
      "get": {
        "description": "Status, the columns found with what Tolvi suggests for each, and counts. Poll this while it reads, checks or imports.\n\nScopes: `clients:read`. Part of the `hub` product: the firm must have it and you must have access to it.",
        "operationId": "Imports_get",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ImportBatch"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "clients:read"
            ]
          }
        ],
        "summary": "Get an import",
        "tags": [
          "Imports"
        ],
        "x-required-scopes": [
          "clients:read"
        ],
        "x-required-product": "hub"
      },
      "delete": {
        "description": "Removes the file and what was read, before anything has come in. A signed-in manager, partner or firm admin, never an API credential or assistant: a person always confirms what comes in.\n\nNeeds the Manager role or above. Part of the `hub` product: the firm must have it and you must have access to it. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "Imports_discard",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Gone.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Discard an import",
        "tags": [
          "Imports"
        ],
        "x-required-role": "manager",
        "x-required-product": "hub",
        "x-session-only": true
      }
    },
    "/api/v1/imports/{id}/uploaded": {
      "post": {
        "description": "Checks what storage holds, hands it to the malware scan and, once clean, reads it. A signed-in manager, partner or firm admin, never an API credential or assistant: a person always confirms what comes in.\n\nNeeds the Manager role or above. Part of the `hub` product: the firm must have it and you must have access to it. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "Imports_uploaded",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ImportBatch"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Say the file has uploaded",
        "tags": [
          "Imports"
        ],
        "x-required-role": "manager",
        "x-required-product": "hub",
        "x-session-only": true
      }
    },
    "/api/v1/imports/{id}/layout": {
      "put": {
        "description": "Reads the file again from another sheet or heading row. A signed-in manager, partner or firm admin, never an API credential or assistant: a person always confirms what comes in.\n\nNeeds the Manager role or above. Part of the `hub` product: the firm must have it and you must have access to it. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "Imports_layout",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ImportLayoutRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ImportBatch"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Choose the sheet or heading row",
        "tags": [
          "Imports"
        ],
        "x-required-role": "manager",
        "x-required-product": "hub",
        "x-session-only": true
      }
    },
    "/api/v1/imports/{id}/mapping": {
      "put": {
        "description": "Says which column is which field, then checks every row in the background. Nothing comes in yet. A signed-in manager, partner or firm admin, never an API credential or assistant: a person always confirms what comes in.\n\nNeeds the Manager role or above. Part of the `hub` product: the firm must have it and you must have access to it. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "Imports_mapping",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ImportMappingRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ImportBatch"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Confirm the columns",
        "tags": [
          "Imports"
        ],
        "x-required-role": "manager",
        "x-required-product": "hub",
        "x-session-only": true
      }
    },
    "/api/v1/imports/{id}/rows": {
      "get": {
        "description": "What each row said, what’s wrong with it in plain words, any client it matches, and what happened to it.\n\nScopes: `clients:read`. Part of the `hub` product: the firm must have it and you must have access to it.",
        "operationId": "Imports_rows",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "after",
            "required": false,
            "in": "query",
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "outcome",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "status",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ImportRowPage"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "clients:read"
            ]
          }
        ],
        "summary": "List an import’s rows",
        "tags": [
          "Imports"
        ],
        "x-required-scopes": [
          "clients:read"
        ],
        "x-required-product": "hub"
      }
    },
    "/api/v1/imports/{id}/rows/{line}": {
      "patch": {
        "description": "Bring it in, fill the blanks on the matching client, or skip it; or give the client type or statement line it lacks. A signed-in manager, partner or firm admin, never an API credential or assistant: a person always confirms what comes in.\n\nNeeds the Manager role or above. Part of the `hub` product: the firm must have it and you must have access to it. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "Imports_patchRow",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "line",
            "required": true,
            "in": "path",
            "schema": {
              "type": "integer"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ImportRowPatchRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ImportRow"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Decide one row",
        "tags": [
          "Imports"
        ],
        "x-required-role": "manager",
        "x-required-product": "hub",
        "x-session-only": true
      }
    },
    "/api/v1/imports/{id}/rows/decide": {
      "post": {
        "description": "For instance, fill the blanks on every duplicate. A signed-in manager, partner or firm admin, never an API credential or assistant: a person always confirms what comes in.\n\nNeeds the Manager role or above. Part of the `hub` product: the firm must have it and you must have access to it. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "Imports_decide",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ImportBulkDecisionRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ImportBatch"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Decide every row of a status",
        "tags": [
          "Imports"
        ],
        "x-required-role": "manager",
        "x-required-product": "hub",
        "x-session-only": true
      }
    },
    "/api/v1/imports/{id}/confirm": {
      "post": {
        "description": "Brings in the rows chosen, in the background. Safe to retry. A signed-in manager, partner or firm admin, never an API credential or assistant: a person always confirms what comes in.\n\nNeeds the Manager role or above. Part of the `hub` product: the firm must have it and you must have access to it. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "Imports_confirm",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ImportConfirmRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ImportBatch"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Confirm and import",
        "tags": [
          "Imports"
        ],
        "x-required-role": "manager",
        "x-required-product": "hub",
        "x-session-only": true
      }
    },
    "/api/v1/imports/{id}/retry": {
      "post": {
        "description": "Rows already done are left alone. A signed-in manager, partner or firm admin, never an API credential or assistant: a person always confirms what comes in.\n\nNeeds the Manager role or above. Part of the `hub` product: the firm must have it and you must have access to it. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "Imports_retry",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ImportBatch"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Carry on after a stop",
        "tags": [
          "Imports"
        ],
        "x-required-role": "manager",
        "x-required-product": "hub",
        "x-session-only": true
      }
    },
    "/api/v1/imports/{id}/undo": {
      "post": {
        "description": "Takes out what the whole file brought in. A client with work on it, or anything changed since, is kept, and the report says why. A signed-in manager, partner or firm admin, never an API credential or assistant: a person always confirms what comes in.\n\nNeeds the Manager role or above. Part of the `hub` product: the firm must have it and you must have access to it. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "Imports_undo",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ImportBatch"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Undo an import",
        "tags": [
          "Imports"
        ],
        "x-required-role": "manager",
        "x-required-product": "hub",
        "x-session-only": true
      }
    },
    "/api/v1/imports/{id}/report": {
      "get": {
        "description": "What happened to every row, as CSV. Values that a spreadsheet would run as a formula are neutralised.\n\nScopes: `clients:read`. Part of the `hub` product: the firm must have it and you must have access to it.",
        "operationId": "Imports_report",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A CSV file.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "clients:read"
            ]
          }
        ],
        "summary": "Download the results report",
        "tags": [
          "Imports"
        ],
        "x-required-scopes": [
          "clients:read"
        ],
        "x-required-product": "hub"
      }
    },
    "/api/v1/health": {
      "get": {
        "operationId": "Health_health",
        "parameters": [],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Health"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "summary": "Check the API and its database",
        "tags": [
          "Health"
        ]
      }
    },
    "/.well-known/oauth-protected-resource": {
      "get": {
        "description": "Where OAuth 2.1 and MCP clients find the authorization server.",
        "operationId": "ProtectedResource_metadata",
        "parameters": [],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProtectedResourceMetadata"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "summary": "OAuth protected-resource metadata",
        "tags": [
          "OAuth"
        ]
      }
    },
    "/api/v1/auth/config": {
      "get": {
        "description": "With `app=books`, the settings for the Tolvi Books app, which signs business owners in with their own account (no organisation).",
        "operationId": "AuthConfig_get",
        "parameters": [
          {
            "name": "app",
            "required": false,
            "in": "query",
            "description": "Which Tolvi app is signing in. Defaults to web (practices).",
            "schema": {
              "$ref": "#/components/schemas/SignInApp"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AuthConfig"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "summary": "Get sign-in settings for the web app",
        "tags": [
          "Sign-in"
        ]
      }
    },
    "/api/v1/me": {
      "get": {
        "description": "Sign-in tokens only, not API tokens.",
        "operationId": "Me_me",
        "parameters": [],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Me"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get the signed-in user and their firms",
        "tags": [
          "Sign-in"
        ]
      }
    },
    "/api/v1/me/other-app": {
      "get": {
        "description": "For the app you signed in to, says whether you are also a member in the other one (Tolvi Books for a business, the Tolvi web app for a practice), and whether an invitation for it is waiting for your verified email address. A yes or no about you, with no firm names or ids. Answers people who have no firm in this app yet. Sign-in tokens from the Tolvi apps only, not API tokens, connected apps or MCP.",
        "operationId": "OtherApp_otherApp",
        "parameters": [],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OtherApp"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Find out whether you also belong in the other Tolvi app",
        "tags": [
          "Sign-in"
        ]
      }
    },
    "/api/v1/clients/{clientId}/links": {
      "get": {
        "description": "Companies this person is connected with, or people connected with this company.\n\nScopes: `clients:read`.",
        "operationId": "ClientLinks_list",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "clientId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ClientLinkList"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "clients:read"
            ]
          }
        ],
        "summary": "List a client’s links",
        "tags": [
          "Clients"
        ],
        "x-required-scopes": [
          "clients:read"
        ]
      },
      "post": {
        "description": "Both are this firm’s clients; the company must be a limited company. A link only ever produces suggestions.\n\nScopes: `clients:write`.",
        "operationId": "ClientLinks_create",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "clientId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateClientLinkRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ClientLink"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "clients:write"
            ]
          }
        ],
        "summary": "Link a person and a company",
        "tags": [
          "Clients"
        ],
        "x-required-scopes": [
          "clients:write"
        ]
      }
    },
    "/api/v1/clients/{clientId}/links/{linkId}": {
      "patch": {
        "operationId": "ClientLinks_update",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "clientId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "linkId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateClientLinkRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ClientLink"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "clients:write"
            ]
          }
        ],
        "summary": "Change a link",
        "tags": [
          "Clients"
        ],
        "x-required-scopes": [
          "clients:write"
        ],
        "description": "Scopes: `clients:write`."
      },
      "delete": {
        "description": "Figures already accepted stay where they are.\n\nScopes: `clients:write`.",
        "operationId": "ClientLinks_remove",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "clientId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "linkId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "clients:write"
            ]
          }
        ],
        "summary": "Remove a link",
        "tags": [
          "Clients"
        ],
        "x-required-scopes": [
          "clients:write"
        ]
      }
    },
    "/api/v1/cross-product-suggestions": {
      "get": {
        "description": "Reads only, and only from products this person holds. Each comes with its source.\n\nScopes: `clients:read`.",
        "operationId": "CrossProductSuggestions_list",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "The return or set of accounts."
          },
          {
            "name": "product",
            "required": true,
            "in": "query",
            "schema": {
              "enum": [
                "self_assessment",
                "corporation_tax",
                "accounts"
              ],
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CrossProductSuggestions"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "clients:read"
            ]
          }
        ],
        "summary": "What a linked client’s other work suggests here",
        "tags": [
          "Clients"
        ],
        "x-required-scopes": [
          "clients:read"
        ]
      }
    },
    "/api/v1/cross-product-suggestions/decide": {
      "post": {
        "description": "A signed-in person only, never an API key or connected assistant. Accepting writes through the target product’s own save, so an approved return goes back to draft. The decision is kept. A suggestion comes back if its source changes.\n\nScopes: `clients:read`. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "CrossProductSuggestions_decide",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DecideCrossProductSuggestionRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CrossProductSuggestions"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Accept or dismiss a suggestion",
        "tags": [
          "Clients"
        ],
        "x-required-scopes": [
          "clients:read"
        ],
        "x-session-only": true
      }
    },
    "/api/v1/clients": {
      "get": {
        "description": "Sorted by name. Each row has the latest engagement’s partner and manager, the bookkeeping connection and the next filing deadline.\n\nScopes: `clients:read`.",
        "operationId": "Clients_list",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 50
            }
          },
          {
            "name": "cursor",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "status",
            "required": false,
            "in": "query",
            "schema": {
              "$ref": "#/components/schemas/ClientStatus"
            }
          },
          {
            "name": "connection",
            "required": false,
            "in": "query",
            "schema": {
              "$ref": "#/components/schemas/ClientConnectionState"
            }
          },
          {
            "name": "yearEndMonth",
            "required": false,
            "in": "query",
            "description": "Year end month (the client’s own, or its latest engagement’s).",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 12
            }
          },
          {
            "name": "entityType",
            "required": false,
            "in": "query",
            "schema": {
              "$ref": "#/components/schemas/EntityType"
            }
          },
          {
            "name": "software",
            "required": false,
            "in": "query",
            "schema": {
              "$ref": "#/components/schemas/Software"
            }
          },
          {
            "name": "manager",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "partner",
            "required": false,
            "in": "query",
            "description": "Partner on any of the client’s engagements.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "q",
            "required": false,
            "in": "query",
            "description": "Part of the client name or company number.",
            "schema": {
              "type": "string",
              "maxLength": 100
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ClientPage"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "clients:read"
            ]
          }
        ],
        "summary": "List or search clients",
        "tags": [
          "Clients"
        ],
        "x-required-scopes": [
          "clients:read"
        ]
      },
      "post": {
        "operationId": "Clients_create",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "A unique key (1-255 visible characters) to make retries safe. Replayed for 24 hours.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateClientRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Client"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "A request with this Idempotency-Key is still being processed.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "422": {
            "description": "This Idempotency-Key was already used for a different request.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "clients:write"
            ]
          }
        ],
        "summary": "Create a client",
        "tags": [
          "Clients"
        ],
        "x-required-scopes": [
          "clients:write"
        ],
        "description": "Scopes: `clients:write`."
      }
    },
    "/api/v1/clients/duplicates": {
      "get": {
        "description": "Call before creating a client. Matches the name ignoring case, punctuation and spacing (\"&\" = \"and\", \"Limited\" = \"Ltd\"), and the Companies House number when given. Advisory: creating a client is never blocked, so show the matches and let the person open one or add anyway.\n\nScopes: `clients:read`.",
        "operationId": "Clients_duplicates",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "companyNumber",
            "required": false,
            "in": "query",
            "description": "The new client’s Companies House number.",
            "schema": {
              "type": "string",
              "maxLength": 8
            }
          },
          {
            "name": "name",
            "required": false,
            "in": "query",
            "description": "The new client’s name.",
            "schema": {
              "type": "string",
              "maxLength": 200
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DuplicateClients"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "clients:read"
            ]
          }
        ],
        "summary": "Find existing clients a new one may duplicate",
        "tags": [
          "Clients"
        ],
        "x-required-scopes": [
          "clients:read"
        ]
      }
    },
    "/api/v1/hub/home": {
      "get": {
        "description": "How many clients the firm has, your work and your meetings today, in one read. A product’s part is null when you can’t use it or the credential has no scope for it.\n\nScopes: `clients:read`. Part of the `hub` product: the firm must have it and you must have access to it.",
        "operationId": "Hub_home",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HubHome"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "clients:read"
            ]
          }
        ],
        "summary": "Get the home page",
        "tags": [
          "Tolvi Hub"
        ],
        "x-required-scopes": [
          "clients:read"
        ],
        "x-required-product": "hub"
      }
    },
    "/api/v1/hub/work-items": {
      "get": {
        "description": "Engagements, self assessment returns, accounts and Company Tax Returns in one list, soonest deadline first. Only products you can use and your credential has a scope for are looked in. Complete work is left out unless you ask for it. Accounts count as complete once approved, because filing at Companies House isn’t recorded.\n\nScopes: `clients:read`. Part of the `hub` product: the firm must have it and you must have access to it.",
        "operationId": "Hub_workItems",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 500,
              "default": 50
            }
          },
          {
            "name": "cursor",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "updatedFrom",
            "required": false,
            "in": "query",
            "description": "Last changed on or after this date.",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "openPoints",
            "required": false,
            "in": "query",
            "description": "true: has open review points.",
            "schema": {
              "type": "string",
              "enum": [
                "true",
                "false"
              ]
            }
          },
          {
            "name": "atRisk",
            "required": false,
            "in": "query",
            "description": "true: due within 30 days and not yet in review.",
            "schema": {
              "type": "string",
              "enum": [
                "true",
                "false"
              ]
            }
          },
          {
            "name": "ownerId",
            "required": false,
            "in": "query",
            "description": "Who acts next: a person’s id, or none for work nobody holds yet.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "includeCompleted",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "true",
                "false"
              ]
            }
          },
          {
            "name": "overdue",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "true",
                "false"
              ]
            }
          },
          {
            "name": "dueTo",
            "required": false,
            "in": "query",
            "description": "Any of its deadlines on or before this date.",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "dueFrom",
            "required": false,
            "in": "query",
            "description": "Any of its deadlines on or after this date.",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "clientId",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "q",
            "required": false,
            "in": "query",
            "description": "Part of the client name.",
            "schema": {
              "type": "string",
              "maxLength": 100
            }
          },
          {
            "name": "stage",
            "required": false,
            "in": "query",
            "schema": {
              "$ref": "#/components/schemas/WorkItemStage"
            }
          },
          {
            "name": "product",
            "required": false,
            "in": "query",
            "schema": {
              "$ref": "#/components/schemas/WorkItemProduct"
            }
          },
          {
            "name": "scope",
            "required": false,
            "in": "query",
            "description": "mine: work you prepare or review, or whose client you answer for. turn: you act next. review: waiting for your review. Left out: all.",
            "schema": {
              "enum": [
                "mine",
                "turn",
                "review",
                "all"
              ],
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WorkItemPage"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "clients:read"
            ]
          }
        ],
        "summary": "List work across the products",
        "tags": [
          "Tolvi Hub"
        ],
        "x-required-scopes": [
          "clients:read"
        ],
        "x-required-product": "hub"
      }
    },
    "/api/v1/hub/widgets": {
      "get": {
        "description": "The catalogue: each widget’s purpose, where its figures come from, its usual size and who can see it. Widgets for apps you can’t use are left out.\n\nScopes: `clients:read`. Part of the `hub` product: the firm must have it and you must have access to it.",
        "operationId": "Dashboards_widgets",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HubWidgetCatalogue"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "clients:read"
            ]
          }
        ],
        "summary": "List the dashboard widgets you can see",
        "tags": [
          "Tolvi Hub"
        ],
        "x-required-scopes": [
          "clients:read"
        ],
        "x-required-product": "hub"
      }
    },
    "/api/v1/hub/widgets/{key}": {
      "get": {
        "description": "Read from the product that holds them when you ask, so nothing can go stale. Money is in integer pence. Each number says which query on GET /hub/work-items shows the work behind it. Refused with 403 when the widget needs an app or a scope you don’t have.\n\nScopes: `clients:read`. Part of the `hub` product: the firm must have it and you must have access to it.",
        "operationId": "Dashboards_widget",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "key",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "enum": [
                "my_deadlines",
                "team_workload",
                "deadlines_by_week",
                "overdue_at_risk",
                "awaiting_review",
                "open_review_points",
                "work_by_status",
                "completed_this_month",
                "recent_notifications",
                "meetings_today",
                "recently_opened",
                "changed_source_files",
                "ai_tokens",
                "imports_in_progress"
              ]
            }
          },
          {
            "name": "product",
            "required": false,
            "in": "query",
            "description": "Only this app’s work. Refused where the widget doesn’t offer it.",
            "schema": {
              "$ref": "#/components/schemas/WorkItemProduct"
            }
          },
          {
            "name": "scope",
            "required": false,
            "in": "query",
            "description": "mine: work you answer for. all: everyone’s. Refused where the widget doesn’t offer it.",
            "schema": {
              "$ref": "#/components/schemas/HubWidgetScope"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HubWidgetData"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "clients:read"
            ]
          }
        ],
        "summary": "Get one widget’s figures",
        "tags": [
          "Tolvi Hub"
        ],
        "x-required-scopes": [
          "clients:read"
        ],
        "x-required-product": "hub"
      }
    },
    "/api/v1/hub/dashboards": {
      "get": {
        "description": "The presets for the apps you can use, your own and those shared with the firm, with which to open first. A preset’s layout leaves out widgets you can’t see.\n\nScopes: `clients:read`. Part of the `hub` product: the firm must have it and you must have access to it.",
        "operationId": "Dashboards_list",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HubDashboardList"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "clients:read"
            ]
          }
        ],
        "summary": "List dashboards",
        "tags": [
          "Tolvi Hub"
        ],
        "x-required-scopes": [
          "clients:read"
        ],
        "x-required-product": "hub"
      },
      "post": {
        "description": "Anyone in the firm can make a dashboard, private or shared with the firm. To duplicate one, send its layout under a new name. Signed-in people only.\n\nScopes: `clients:read`. Part of the `hub` product: the firm must have it and you must have access to it. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "Dashboards_create",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "A unique key (1-255 visible characters) to make retries safe. Replayed for 24 hours.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateHubDashboard"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HubDashboard"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "A request with this Idempotency-Key is still being processed.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "422": {
            "description": "This Idempotency-Key was already used for a different request.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Save a new dashboard",
        "tags": [
          "Tolvi Hub"
        ],
        "x-required-scopes": [
          "clients:read"
        ],
        "x-required-product": "hub",
        "x-session-only": true
      }
    },
    "/api/v1/hub/dashboards/default": {
      "put": {
        "description": "A preset or a dashboard you can see. If it later goes, Home opens the preset for your role. Signed-in people only.\n\nScopes: `clients:read`. Part of the `hub` product: the firm must have it and you must have access to it. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "Dashboards_setDefault",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SetHubDefaultDashboard"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SetHubDefaultDashboard"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Choose your default dashboard",
        "tags": [
          "Tolvi Hub"
        ],
        "x-required-scopes": [
          "clients:read"
        ],
        "x-required-product": "hub",
        "x-session-only": true
      }
    },
    "/api/v1/hub/dashboards/{id}": {
      "patch": {
        "description": "Name, layout or who sees it. Its creator, or for a shared dashboard a manager and above. Others can duplicate it and change their copy. Only its creator can make a shared one private. Signed-in people only.\n\nScopes: `clients:read`. Part of the `hub` product: the firm must have it and you must have access to it. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "Dashboards_update",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateHubDashboard"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HubDashboard"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Change a dashboard",
        "tags": [
          "Tolvi Hub"
        ],
        "x-required-scopes": [
          "clients:read"
        ],
        "x-required-product": "hub",
        "x-session-only": true
      },
      "delete": {
        "description": "Its creator, or for a shared dashboard a manager and above. Others can duplicate it and change their copy. Signed-in people only.\n\nScopes: `clients:read`. Part of the `hub` product: the firm must have it and you must have access to it. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "Dashboards_remove",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Gone.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Delete a dashboard",
        "tags": [
          "Tolvi Hub"
        ],
        "x-required-scopes": [
          "clients:read"
        ],
        "x-required-product": "hub",
        "x-session-only": true
      }
    },
    "/api/v1/clients/{clientId}/overview": {
      "get": {
        "description": "The record, and what each product holds about the client: status, next deadline, latest figures, tax due, review points. Each part comes from its own product, and is null when you can’t use that product or your credential has no scope for it; `unavailable` names those.\n\nScopes: `clients:read`. Part of the `hub` product: the firm must have it and you must have access to it.",
        "operationId": "ClientRecord_overview",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "clientId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ClientOverview"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "clients:read"
            ]
          }
        ],
        "summary": "Get one client across the suite",
        "tags": [
          "Tolvi Hub"
        ],
        "x-required-scopes": [
          "clients:read"
        ],
        "x-required-product": "hub"
      }
    },
    "/api/v1/clients/{clientId}/period-chain": {
      "get": {
        "description": "Books, year-end file, accounts, CT return and filing for one year end, each with its status and the id to open. Only products you can use have a step, and only those the client’s type can have. Filing from Tolvi is marked as coming; a date a person recorded is shown as recorded.\n\nScopes: `clients:read`. Part of the `hub` product: the firm must have it and you must have access to it.",
        "operationId": "ClientRecord_periodChain",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "clientId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "periodEnd",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date"
            },
            "description": "The year end. Defaults to the latest with work."
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PeriodChain"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "clients:read"
            ]
          }
        ],
        "summary": "Get one year end across the products",
        "tags": [
          "Tolvi Hub"
        ],
        "x-required-scopes": [
          "clients:read"
        ],
        "x-required-product": "hub"
      }
    },
    "/api/v1/clients/{clientId}/record": {
      "get": {
        "description": "Details, identifiers, status, services, people and contacts, with what Working Papers, Meetings and the books hold about the client. A product’s part is null when you can’t use it or the credential has no scope for it.\n\nScopes: `clients:read`. Part of the `hub` product: the firm must have it and you must have access to it.",
        "operationId": "ClientRecord_record",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "clientId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ClientRecord"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "clients:read"
            ]
          }
        ],
        "summary": "Get the client’s central record",
        "tags": [
          "Tolvi Hub"
        ],
        "x-required-scopes": [
          "clients:read"
        ],
        "x-required-product": "hub"
      },
      "patch": {
        "description": "Preparers and above. Refused when an identifier isn’t in the right form, or the responsible partner or client manager doesn’t hold that role in this firm. Doesn’t change who is assigned to any engagement.\n\nNeeds the Preparer role or above. Scopes: `clients:write`. Part of the `hub` product: the firm must have it and you must have access to it.",
        "operationId": "ClientRecord_update",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "clientId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateClientRecordRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ClientRecord"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "clients:write"
            ]
          }
        ],
        "summary": "Change the client’s central record",
        "tags": [
          "Tolvi Hub"
        ],
        "x-required-role": "preparer",
        "x-required-scopes": [
          "clients:write"
        ],
        "x-required-product": "hub"
      }
    },
    "/api/v1/clients/{clientId}/company-facts": {
      "get": {
        "description": "Registered office, principal activity, signatory and directors, as Accounts and Corporation Tax read them.\n\nScopes: `clients:read`. Part of the `hub` product: the firm must have it and you must have access to it.",
        "operationId": "ClientRecord_companyFacts",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "clientId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CompanyFacts"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "clients:read"
            ]
          }
        ],
        "summary": "Get the company facts on the record",
        "tags": [
          "Tolvi Hub"
        ],
        "x-required-scopes": [
          "clients:read"
        ],
        "x-required-product": "hub"
      }
    },
    "/api/v1/clients/{clientId}/directors": {
      "put": {
        "description": "Preparers and above. Adds each person as a contact with the role Director, or updates their dates. Nobody is removed: take someone off in Contacts.\n\nNeeds the Preparer role or above. Scopes: `clients:write`. Part of the `hub` product: the firm must have it and you must have access to it.",
        "operationId": "ClientRecord_saveDirectors",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "clientId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SaveDirectorsRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CompanyFacts"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "clients:write"
            ]
          }
        ],
        "summary": "Save directors to the record",
        "tags": [
          "Tolvi Hub"
        ],
        "x-required-role": "preparer",
        "x-required-scopes": [
          "clients:write"
        ],
        "x-required-product": "hub"
      }
    },
    "/api/v1/clients/{clientId}/contacts": {
      "post": {
        "description": "Preparers and above. The client’s first contact becomes its primary contact.\n\nNeeds the Preparer role or above. Scopes: `clients:write`. Part of the `hub` product: the firm must have it and you must have access to it.",
        "operationId": "ClientRecord_addContact",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "clientId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "A unique key (1-255 visible characters) to make retries safe. Replayed for 24 hours.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateClientContactRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ClientContact"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "A request with this Idempotency-Key is still being processed.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "422": {
            "description": "This Idempotency-Key was already used for a different request.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "clients:write"
            ]
          }
        ],
        "summary": "Add a contact",
        "tags": [
          "Tolvi Hub"
        ],
        "x-required-role": "preparer",
        "x-required-scopes": [
          "clients:write"
        ],
        "x-required-product": "hub"
      }
    },
    "/api/v1/clients/{clientId}/contacts/{contactId}": {
      "patch": {
        "description": "Preparers and above.\n\nNeeds the Preparer role or above. Scopes: `clients:write`. Part of the `hub` product: the firm must have it and you must have access to it.",
        "operationId": "ClientRecord_updateContact",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "clientId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "contactId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateClientContactRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ClientContact"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "clients:write"
            ]
          }
        ],
        "summary": "Change a contact",
        "tags": [
          "Tolvi Hub"
        ],
        "x-required-role": "preparer",
        "x-required-scopes": [
          "clients:write"
        ],
        "x-required-product": "hub"
      },
      "delete": {
        "description": "Preparers and above. If it was the primary contact, the next by name takes over.\n\nNeeds the Preparer role or above. Scopes: `clients:write`. Part of the `hub` product: the firm must have it and you must have access to it.",
        "operationId": "ClientRecord_removeContact",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "clientId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "contactId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Removed.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "clients:write"
            ]
          }
        ],
        "summary": "Remove a contact",
        "tags": [
          "Tolvi Hub"
        ],
        "x-required-role": "preparer",
        "x-required-scopes": [
          "clients:write"
        ],
        "x-required-product": "hub"
      }
    },
    "/api/v1/client-list/fields": {
      "get": {
        "description": "One group per module, with each field’s type and what it can be filtered by. Only modules for products you can use, and your credential has a scope for.\n\nScopes: `clients:read`. Part of the `hub` product: the firm must have it and you must have access to it.",
        "operationId": "ClientList_fields",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ClientFieldCatalogue"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "clients:read"
            ]
          }
        ],
        "summary": "List the fields of the client list",
        "tags": [
          "Client list"
        ],
        "x-required-scopes": [
          "clients:read"
        ],
        "x-required-product": "hub"
      }
    },
    "/api/v1/client-list": {
      "get": {
        "description": "Filtered, sorted and paged on the server, with data from every product you can use. Only fields in the catalogue can be named.\n\nScopes: `clients:read`. Part of the `hub` product: the firm must have it and you must have access to it.",
        "operationId": "ClientList_query",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50
            }
          },
          {
            "name": "page",
            "required": false,
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            }
          },
          {
            "name": "q",
            "required": false,
            "in": "query",
            "description": "Part of the client name or company number.",
            "schema": {
              "type": "string",
              "maxLength": 100
            }
          },
          {
            "name": "sort",
            "required": false,
            "in": "query",
            "description": "A field id, with a leading - for descending. Blanks come last. Name, then id, break ties.",
            "schema": {
              "type": "string",
              "maxLength": 61
            }
          },
          {
            "name": "columns",
            "required": false,
            "in": "query",
            "description": "Field ids, comma separated. Left out: the default columns.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "filter",
            "required": false,
            "in": "query",
            "description": "JSON: `{ \"match\": \"all\", \"conditions\": [{ \"field\": \"ct.due\", \"operator\": \"next_days\", \"value\": 30 }] }`. Groups nest. Conditions on a product you can’t use aren’t applied, and are named in hiddenFields.",
            "schema": {
              "type": "string",
              "maxLength": 8000
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ClientListPage"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "clients:read"
            ]
          }
        ],
        "summary": "List clients with chosen columns and filters",
        "tags": [
          "Client list"
        ],
        "x-required-scopes": [
          "clients:read"
        ],
        "x-required-product": "hub"
      }
    },
    "/api/v1/client-list/export": {
      "get": {
        "description": "The same filter, sort and columns as the list, every matching row, up to 10,000. Money is in pounds, with credits in brackets. Refused when it’s more than that, or SA tax due is a column and more than 500 clients match.\n\nScopes: `clients:read`. Part of the `hub` product: the firm must have it and you must have access to it.",
        "operationId": "ClientList_exportCsv",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "q",
            "required": false,
            "in": "query",
            "description": "Part of the client name or company number.",
            "schema": {
              "type": "string",
              "maxLength": 100
            }
          },
          {
            "name": "sort",
            "required": false,
            "in": "query",
            "description": "A field id, with a leading - for descending. Blanks come last. Name, then id, break ties.",
            "schema": {
              "type": "string",
              "maxLength": 61
            }
          },
          {
            "name": "columns",
            "required": false,
            "in": "query",
            "description": "Field ids, comma separated. Left out: the default columns.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "filter",
            "required": false,
            "in": "query",
            "description": "JSON: `{ \"match\": \"all\", \"conditions\": [{ \"field\": \"ct.due\", \"operator\": \"next_days\", \"value\": 30 }] }`. Groups nest. Conditions on a product you can’t use aren’t applied, and are named in hiddenFields.",
            "schema": {
              "type": "string",
              "maxLength": 8000
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The CSV.",
            "content": {
              "text/csv": {
                "schema": {
                  "type": "string"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "clients:read"
            ]
          }
        ],
        "summary": "Export the client list as CSV",
        "tags": [
          "Client list"
        ],
        "x-required-scopes": [
          "clients:read"
        ],
        "x-required-product": "hub"
      }
    },
    "/api/v1/client-list/views": {
      "get": {
        "description": "Those shared with the practice, and your own private ones.\n\nScopes: `clients:read`. Part of the `hub` product: the firm must have it and you must have access to it.",
        "operationId": "ClientList_listViews",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ClientListViews"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "clients:read"
            ]
          }
        ],
        "summary": "List saved views",
        "tags": [
          "Client list"
        ],
        "x-required-scopes": [
          "clients:read"
        ],
        "x-required-product": "hub"
      },
      "post": {
        "description": "Anyone signed in can save one, private or shared with the practice. An API credential also needs clients:write.\n\nScopes: `clients:read`. Part of the `hub` product: the firm must have it and you must have access to it.",
        "operationId": "ClientList_createView",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "A unique key (1-255 visible characters) to make retries safe. Replayed for 24 hours.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateClientListViewRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ClientListView"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "A request with this Idempotency-Key is still being processed.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "422": {
            "description": "This Idempotency-Key was already used for a different request.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "clients:read"
            ]
          }
        ],
        "summary": "Save a view",
        "tags": [
          "Client list"
        ],
        "x-required-scopes": [
          "clients:read"
        ],
        "x-required-product": "hub"
      }
    },
    "/api/v1/client-list/views/{viewId}": {
      "patch": {
        "description": "Its creator, or for a shared view a manager or above. Only its creator can change who sees it. Someone else’s private view is 404.\n\nScopes: `clients:read`. Part of the `hub` product: the firm must have it and you must have access to it.",
        "operationId": "ClientList_updateView",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "viewId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateClientListViewRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ClientListView"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "clients:read"
            ]
          }
        ],
        "summary": "Change a saved view",
        "tags": [
          "Client list"
        ],
        "x-required-scopes": [
          "clients:read"
        ],
        "x-required-product": "hub"
      },
      "delete": {
        "description": "Its creator, or for a shared view a manager or above.\n\nScopes: `clients:read`. Part of the `hub` product: the firm must have it and you must have access to it.",
        "operationId": "ClientList_deleteView",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "viewId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Deleted.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "clients:read"
            ]
          }
        ],
        "summary": "Delete a saved view",
        "tags": [
          "Client list"
        ],
        "x-required-scopes": [
          "clients:read"
        ],
        "x-required-product": "hub"
      }
    },
    "/api/v1/client-list/views/{viewId}/duplicate": {
      "post": {
        "description": "The copy is yours, and private.\n\nScopes: `clients:read`. Part of the `hub` product: the firm must have it and you must have access to it.",
        "operationId": "ClientList_duplicateView",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "viewId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "A unique key (1-255 visible characters) to make retries safe. Replayed for 24 hours.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            }
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DuplicateClientListViewRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ClientListView"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "A request with this Idempotency-Key is still being processed.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "422": {
            "description": "This Idempotency-Key was already used for a different request.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "clients:read"
            ]
          }
        ],
        "summary": "Duplicate a saved view",
        "tags": [
          "Client list"
        ],
        "x-required-scopes": [
          "clients:read"
        ],
        "x-required-product": "hub"
      }
    },
    "/api/v1/client-list/views/{viewId}/default": {
      "put": {
        "description": "For you alone.\n\nScopes: `clients:read`. Part of the `hub` product: the firm must have it and you must have access to it.",
        "operationId": "ClientList_setDefault",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "viewId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ClientListView"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "clients:read"
            ]
          }
        ],
        "summary": "Open the client list on this view",
        "tags": [
          "Client list"
        ],
        "x-required-scopes": [
          "clients:read"
        ],
        "x-required-product": "hub"
      }
    },
    "/api/v1/client-list/default-view": {
      "delete": {
        "operationId": "ClientList_clearDefault",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Cleared.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "clients:read"
            ]
          }
        ],
        "summary": "Stop opening the client list on a saved view",
        "tags": [
          "Client list"
        ],
        "x-required-scopes": [
          "clients:read"
        ],
        "x-required-product": "hub",
        "description": "Scopes: `clients:read`. Part of the `hub` product: the firm must have it and you must have access to it."
      }
    },
    "/api/v1/accounts": {
      "get": {
        "description": "Every client’s accounts, latest period first. Filter by client or status.\n\nScopes: `accounts:read`. Part of the `accounts` product: the firm must have it and you must have access to it.",
        "operationId": "Accounts_list",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "status",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "draft",
                "in_review",
                "approved"
              ]
            }
          },
          {
            "name": "clientId",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AccountsSetList"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "accounts:read"
            ]
          }
        ],
        "summary": "List accounts",
        "tags": [
          "Accounts"
        ],
        "x-required-scopes": [
          "accounts:read"
        ],
        "x-required-product": "accounts"
      },
      "post": {
        "description": "Preparers and above. One set per client and period end, for a company, LLP, sole trader or partnership. No engagement is needed.\n\nNeeds the Preparer role or above. Scopes: `accounts:write`. Part of the `accounts` product: the firm must have it and you must have access to it.",
        "operationId": "Accounts_create",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "A unique key (1-255 visible characters) to make retries safe. Replayed for 24 hours.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateAccountsSetRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AccountsSet"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "A request with this Idempotency-Key is still being processed.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "422": {
            "description": "This Idempotency-Key was already used for a different request.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "accounts:write"
            ]
          }
        ],
        "summary": "Start accounts",
        "tags": [
          "Accounts"
        ],
        "x-required-role": "preparer",
        "x-required-scopes": [
          "accounts:write"
        ],
        "x-required-product": "accounts"
      }
    },
    "/api/v1/accounts/statement-lines": {
      "get": {
        "description": "The lines a trial balance account can go to, in accounts order. `framework=FRS102_FULL` adds intangibles, investments, Format 2 and other comprehensive income.\n\nScopes: `accounts:read`. Part of the `accounts` product: the firm must have it and you must have access to it.",
        "operationId": "Accounts_statementLines",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "entity",
            "required": false,
            "in": "query",
            "description": "`llp` adds members’ lines. `NON_STATUTORY` has capital and drawings.",
            "schema": {
              "enum": [
                "company",
                "llp",
                "sole_trader",
                "partnership",
                "charity"
              ],
              "type": "string"
            }
          },
          {
            "name": "framework",
            "required": false,
            "in": "query",
            "schema": {
              "enum": [
                "FRS105",
                "FRS102_1A",
                "FRS102_FULL",
                "NON_STATUTORY",
                "CHARITY_SORP",
                "CHARITY_RP"
              ],
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AccountsStatementLines"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "accounts:read"
            ]
          }
        ],
        "summary": "List statement lines",
        "tags": [
          "Accounts"
        ],
        "x-required-scopes": [
          "accounts:read"
        ],
        "x-required-product": "accounts"
      }
    },
    "/api/v1/accounts/{id}": {
      "get": {
        "description": "The set, the full version for members and the filleted version prepared for Companies House (or the one asked for), every problem, and whether a linked Working Papers file has changed (`sourceChanged`). A change to the file never moves the figures here. This doesn’t file anything.\n\nScopes: `accounts:read`. Part of the `accounts` product: the firm must have it and you must have access to it.",
        "operationId": "Accounts_get",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "variant",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "full",
                "filleted"
              ]
            },
            "description": "Left out: both versions."
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AccountsSet"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "accounts:read"
            ]
          }
        ],
        "summary": "Get accounts",
        "tags": [
          "Accounts"
        ],
        "x-required-scopes": [
          "accounts:read"
        ],
        "x-required-product": "accounts"
      },
      "patch": {
        "description": "Preparers and above: the company, facts, analyses and note wording. Any real change to approved accounts returns them to draft and loses the approval.\n\nNeeds the Preparer role or above. Scopes: `accounts:write`. Part of the `accounts` product: the firm must have it and you must have access to it.",
        "operationId": "Accounts_update",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateAccountsSetRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AccountsSet"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "accounts:write"
            ]
          }
        ],
        "summary": "Change accounts",
        "tags": [
          "Accounts"
        ],
        "x-required-role": "preparer",
        "x-required-scopes": [
          "accounts:write"
        ],
        "x-required-product": "accounts"
      }
    },
    "/api/v1/accounts/{id}/trial-balance/versions": {
      "get": {
        "description": "Every version, latest first. Versions never change.\n\nScopes: `accounts:read`. Part of the `accounts` product: the firm must have it and you must have access to it.",
        "operationId": "Accounts_versions",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/AccountsTbVersion"
                  }
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "accounts:read"
            ]
          }
        ],
        "summary": "List trial balance versions",
        "tags": [
          "Accounts"
        ],
        "x-required-scopes": [
          "accounts:read"
        ],
        "x-required-product": "accounts"
      },
      "post": {
        "description": "A typed or imported trial balance becomes a new version, with the balance and statement line checks reported as problems. Refused on accounts linked to a Working Papers file.\n\nNeeds the Preparer role or above. Scopes: `accounts:write`. Part of the `accounts` product: the firm must have it and you must have access to it.",
        "operationId": "Accounts_newVersion",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AccountsTbNewVersionRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AccountsSet"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "accounts:write"
            ]
          }
        ],
        "summary": "Add a trial balance version",
        "tags": [
          "Accounts"
        ],
        "x-required-role": "preparer",
        "x-required-scopes": [
          "accounts:write"
        ],
        "x-required-product": "accounts"
      }
    },
    "/api/v1/accounts/{id}/trial-balance/preview": {
      "post": {
        "description": "Reads a CSV or spreadsheet the way Working Papers does and suggests a statement line for each account. Nothing is stored.\n\nNeeds the Preparer role or above. Scopes: `accounts:write`. Part of the `accounts` product: the firm must have it and you must have access to it.",
        "operationId": "Accounts_previewTb",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AccountsTbPreviewRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AccountsTbPreview"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "accounts:write"
            ]
          }
        ],
        "summary": "Read a trial balance file",
        "tags": [
          "Accounts"
        ],
        "x-required-role": "preparer",
        "x-required-scopes": [
          "accounts:write"
        ],
        "x-required-product": "accounts"
      }
    },
    "/api/v1/accounts/{id}/link": {
      "post": {
        "description": "Takes the final trial balance and fixed asset movements of an engagement of the same client and year end as a new version. The file need not be approved yet: if it isn’t, `problems` says so. Needs Working Papers and `engagements:read`.\n\nNeeds the Preparer role or above. Scopes: `accounts:write`. Part of the `accounts` product: the firm must have it and you must have access to it.",
        "operationId": "Accounts_link",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LinkAccountsSetRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AccountsSet"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "accounts:write"
            ]
          }
        ],
        "summary": "Link to a Working Papers file",
        "tags": [
          "Accounts"
        ],
        "x-required-role": "preparer",
        "x-required-scopes": [
          "accounts:write"
        ],
        "x-required-product": "accounts"
      }
    },
    "/api/v1/accounts/{id}/refresh": {
      "post": {
        "description": "A new version from the linked Working Papers file. Figures that change take approved accounts back to draft. Nothing happens if they already match.\n\nNeeds the Preparer role or above. Scopes: `accounts:write`. Part of the `accounts` product: the firm must have it and you must have access to it.",
        "operationId": "Accounts_refresh",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AccountsSet"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "accounts:write"
            ]
          }
        ],
        "summary": "Bring in the file’s latest figures",
        "tags": [
          "Accounts"
        ],
        "x-required-role": "preparer",
        "x-required-scopes": [
          "accounts:write"
        ],
        "x-required-product": "accounts"
      }
    },
    "/api/v1/accounts/{id}/roll-forward": {
      "post": {
        "description": "A new set with the company, facts and note wording carried over, this year’s closing figures as comparatives, and the dates moved on. Link it to next year’s file, or enter its trial balance.\n\nNeeds the Preparer role or above. Scopes: `accounts:write`. Part of the `accounts` product: the firm must have it and you must have access to it.",
        "operationId": "Accounts_rollForward",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RollForwardAccountsSetRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AccountsSet"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "accounts:write"
            ]
          }
        ],
        "summary": "Start next year’s accounts",
        "tags": [
          "Accounts"
        ],
        "x-required-role": "preparer",
        "x-required-scopes": [
          "accounts:write"
        ],
        "x-required-product": "accounts"
      }
    },
    "/api/v1/accounts/{id}/send-for-review": {
      "post": {
        "description": "Preparers and above, from draft. Accounts are approved from here, and any real change takes them back to draft.\n\nNeeds the Preparer role or above. Scopes: `accounts:write`. Part of the `accounts` product: the firm must have it and you must have access to it.",
        "operationId": "Accounts_sendForReview",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SendAccountsForReviewRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AccountsSet"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "accounts:write"
            ]
          }
        ],
        "summary": "Send for review",
        "tags": [
          "Accounts"
        ],
        "x-required-role": "preparer",
        "x-required-scopes": [
          "accounts:write"
        ],
        "x-required-product": "accounts"
      }
    },
    "/api/v1/accounts/{id}/approve": {
      "post": {
        "description": "Partners, signed in, or managers where the firm allows it (403 otherwise). Accounts must have been sent for review, and open review points refuse it with 409. Records the date the board approved the accounts and the director signing, for exactly the figures reviewed (`figuresHash`). Blocking problems refuse it with 409 and the list. Never available to API keys or connected assistants. This doesn’t file anything.\n\nNeeds the Manager role or above. Scopes: `accounts:write`. Part of the `accounts` product: the firm must have it and you must have access to it. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "Accounts_approve",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ApproveAccountsSetRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AccountsSet"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Record the directors’ approval",
        "tags": [
          "Accounts"
        ],
        "x-required-role": "manager",
        "x-required-scopes": [
          "accounts:write"
        ],
        "x-required-product": "accounts",
        "x-session-only": true
      }
    },
    "/api/v1/accounts/{id}/reopen": {
      "post": {
        "description": "Managers and partners, signed in, from review or approved. Back to draft, and any approval is gone. Never available to API keys or connected assistants.\n\nNeeds the Manager role or above. Scopes: `accounts:write`. Part of the `accounts` product: the firm must have it and you must have access to it. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "Accounts_reopen",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ReopenAccountsSetRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AccountsSet"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Reopen accounts",
        "tags": [
          "Accounts"
        ],
        "x-required-role": "manager",
        "x-required-scopes": [
          "accounts:write"
        ],
        "x-required-product": "accounts",
        "x-session-only": true
      }
    },
    "/api/v1/accounts/{id}/revise": {
      "post": {
        "description": "Managers and partners. A new set for the same year from approved accounts, for correcting what didn’t comply with the Companies Act 2006 (s454). The original is kept unchanged, and stays the statutory accounts until the revised accounts are approved. Refused with 409 for accounts not yet approved, or if a revision has already been started.\n\nNeeds the Manager role or above. Scopes: `accounts:write`. Part of the `accounts` product: the firm must have it and you must have access to it.",
        "operationId": "Accounts_revise",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "A unique key (1-255 visible characters) to make retries safe. Replayed for 24 hours.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ReviseAccountsSetRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AccountsSet"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "A request with this Idempotency-Key is still being processed.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "422": {
            "description": "This Idempotency-Key was already used for a different request.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "accounts:write"
            ]
          }
        ],
        "summary": "Start revised accounts",
        "tags": [
          "Accounts"
        ],
        "x-required-role": "manager",
        "x-required-scopes": [
          "accounts:write"
        ],
        "x-required-product": "accounts"
      }
    },
    "/api/v1/accounts/{id}/review-points": {
      "post": {
        "description": "Reviewers and above. Open points stop the approval. Refused with 409 on approved accounts.\n\nNeeds the Reviewer role or above. Scopes: `review:write`. Part of the `accounts` product: the firm must have it and you must have access to it.",
        "operationId": "Accounts_raisePoint",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RaiseAccountsReviewPointRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AccountsSet"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "review:write"
            ]
          }
        ],
        "summary": "Raise a review point",
        "tags": [
          "Accounts"
        ],
        "x-required-role": "reviewer",
        "x-required-scopes": [
          "review:write"
        ],
        "x-required-product": "accounts"
      }
    },
    "/api/v1/accounts/{id}/review-points/{pointId}/clear": {
      "post": {
        "description": "Reviewers and above.\n\nNeeds the Reviewer role or above. Scopes: `review:write`. Part of the `accounts` product: the firm must have it and you must have access to it.",
        "operationId": "Accounts_clearPoint",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "pointId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AccountsSet"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "review:write"
            ]
          }
        ],
        "summary": "Clear a review point",
        "tags": [
          "Accounts"
        ],
        "x-required-role": "reviewer",
        "x-required-scopes": [
          "review:write"
        ],
        "x-required-product": "accounts"
      }
    },
    "/api/v1/accounts/{id}/draft-note": {
      "post": {
        "description": "Preparers and above, signed in. Spends the firm’s Tolvi AI tokens, and the firm’s AI switch applies. Works only from the facts, without figures or names. It returns text for a person to check: nothing is stored or applied, and no figure can change. To accept it, save it through `noteOverrides`.\n\nNeeds the Preparer role or above. Scopes: `accounts:write`. Part of the `accounts` product: the firm must have it and you must have access to it. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "Accounts_draftNote",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DraftAccountsNoteRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AccountsNoteDraft"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Draft a note’s wording with Tolvi AI",
        "tags": [
          "Accounts"
        ],
        "x-required-role": "preparer",
        "x-required-scopes": [
          "accounts:write"
        ],
        "x-required-product": "accounts",
        "x-session-only": true
      }
    },
    "/api/v1/accounts/{id}/pdf": {
      "get": {
        "description": "The full version for members, or the filleted version prepared for Companies House, as a PDF. Every page says \"Draft, not approved\" until people have recorded the directors’ approval. This doesn’t file anything.\n\nScopes: `accounts:read`. Part of the `accounts` product: the firm must have it and you must have access to it.",
        "operationId": "Accounts_pdf",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "variant",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "full",
                "filleted"
              ]
            },
            "description": "Left out: full."
          }
        ],
        "responses": {
          "200": {
            "description": "A PDF.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "accounts:read"
            ]
          }
        ],
        "summary": "Download the accounts",
        "tags": [
          "Accounts"
        ],
        "x-required-scopes": [
          "accounts:read"
        ],
        "x-required-product": "accounts"
      }
    },
    "/api/v1/accounts/{id}/word": {
      "get": {
        "description": "The accounts as a Word document, to read or send on. Every page says \"Draft, not approved\" until the directors’ approval is recorded. A change made in Word doesn’t come back to Tolvi, and Word isn’t a format to file. This doesn’t file anything.\n\nScopes: `accounts:read`. Part of the `accounts` product: the firm must have it and you must have access to it.",
        "operationId": "Accounts_word",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "variant",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "full",
                "filleted"
              ]
            },
            "description": "Left out: full."
          }
        ],
        "responses": {
          "200": {
            "description": "A Word document.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "accounts:read"
            ]
          }
        ],
        "summary": "Export the accounts to Word",
        "tags": [
          "Accounts"
        ],
        "x-required-scopes": [
          "accounts:read"
        ],
        "x-required-product": "accounts"
      }
    },
    "/api/v1/accounts/{id}/ixbrl": {
      "get": {
        "description": "The accounts tagged to the FRC taxonomy. A draft still downloads, to see what would be tagged, and its file name says draft. What stops a file being filed is in `ixbrl` on the set. Neither Companies House nor HMRC has checked these files. This doesn’t file anything.\n\nScopes: `accounts:read`. Part of the `accounts` product: the firm must have it and you must have access to it.",
        "operationId": "Accounts_ixbrl",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "variant",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "full",
                "filleted"
              ]
            },
            "description": "Left out: full."
          }
        ],
        "responses": {
          "200": {
            "description": "iXBRL.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "accounts:read"
            ]
          }
        ],
        "summary": "Download the iXBRL accounts",
        "tags": [
          "Accounts"
        ],
        "x-required-scopes": [
          "accounts:read"
        ],
        "x-required-product": "accounts"
      }
    },
    "/api/v1/accounts/{id}/companies-house/submit": {
      "post": {
        "description": "A manager or partner, signed in with a second factor, once the accounts are approved and nothing Tolvi can check stops the tagged file. Answers 503 while filing is switched off, which it is until Companies House’s test service has been passed. Companies House has not reviewed or accepted this route. Never available to API keys or connected assistants.\n\nNeeds the Manager role or above. Scopes: `accounts:write`. Part of the `accounts` product: the firm must have it and you must have access to it. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "ChFiling_submit",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "A unique key (1-255 visible characters) to make retries safe. Replayed for 24 hours.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SubmitAccountsToCompaniesHouseRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AccountsSet"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "A request with this Idempotency-Key is still being processed.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "422": {
            "description": "This Idempotency-Key was already used for a different request.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "File with Companies House",
        "tags": [
          "Accounts"
        ],
        "x-required-role": "manager",
        "x-required-scopes": [
          "accounts:write"
        ],
        "x-required-product": "accounts",
        "x-session-only": true
      }
    },
    "/api/v1/accounts/{id}/companies-house/submissions/{submissionId}/poll": {
      "post": {
        "description": "While Companies House is checking accounts. Tolvi also asks by itself.\n\nScopes: `accounts:read`. Part of the `accounts` product: the firm must have it and you must have access to it.",
        "operationId": "ChFiling_poll",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "submissionId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AccountsSet"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "accounts:read"
            ]
          }
        ],
        "summary": "Ask Companies House for its answer",
        "tags": [
          "Accounts"
        ],
        "x-required-scopes": [
          "accounts:read"
        ],
        "x-required-product": "accounts"
      }
    },
    "/api/v1/companies-house/presenters": {
      "get": {
        "description": "Names and status only: saved details are never returned.\n\nScopes: `accounts:read`. Part of the `accounts` product: the firm must have it and you must have access to it.",
        "operationId": "ChPresenters_list",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ChPresenterList"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "accounts:read"
            ]
          }
        ],
        "summary": "List Companies House presenters",
        "tags": [
          "Accounts"
        ],
        "x-required-scopes": [
          "accounts:read"
        ],
        "x-required-product": "accounts"
      },
      "post": {
        "description": "Firm admins, signed in. Name it so people can tell them apart.\n\nScopes: `settings:admin`. Part of the `accounts` product: the firm must have it and you must have access to it. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "ChPresenters_create",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateChPresenterRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ChPresenter"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Add a Companies House presenter",
        "tags": [
          "Accounts"
        ],
        "x-required-scopes": [
          "settings:admin"
        ],
        "x-required-product": "accounts",
        "x-session-only": true
      }
    },
    "/api/v1/companies-house/presenters/{presenterId}": {
      "delete": {
        "description": "Firm admins, signed in. Its details are deleted at once.\n\nScopes: `settings:admin`. Part of the `accounts` product: the firm must have it and you must have access to it. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "ChPresenters_remove",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "presenterId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Remove a Companies House presenter",
        "tags": [
          "Accounts"
        ],
        "x-required-scopes": [
          "settings:admin"
        ],
        "x-required-product": "accounts",
        "x-session-only": true
      }
    },
    "/api/v1/companies-house/presenters/{presenterId}/credentials": {
      "put": {
        "description": "Firm admins, signed in. Encrypted, used only when someone allowed to file files accounts, and never shown again.\n\nScopes: `settings:admin`. Part of the `accounts` product: the firm must have it and you must have access to it. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "ChPresenters_save",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "presenterId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SaveChCredentialsRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ChPresenter"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Save the presenter details",
        "tags": [
          "Accounts"
        ],
        "x-required-scopes": [
          "settings:admin"
        ],
        "x-required-product": "accounts",
        "x-session-only": true
      },
      "delete": {
        "description": "Firm admins, signed in.\n\nScopes: `settings:admin`. Part of the `accounts` product: the firm must have it and you must have access to it. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "ChPresenters_removeCredentials",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "presenterId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ChPresenter"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Delete the saved details",
        "tags": [
          "Accounts"
        ],
        "x-required-scopes": [
          "settings:admin"
        ],
        "x-required-product": "accounts",
        "x-session-only": true
      }
    },
    "/api/v1/corporation-tax/returns": {
      "get": {
        "description": "Every company’s returns, latest period first. Filter by client or status.\n\nScopes: `corporation_tax:read`. Part of the `corporation_tax` product: the firm must have it and you must have access to it.",
        "operationId": "CtReturns_list",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "status",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "draft",
                "in_review",
                "approved",
                "filing",
                "filed"
              ]
            }
          },
          {
            "name": "clientId",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CtReturnList"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "corporation_tax:read"
            ]
          }
        ],
        "summary": "List returns",
        "tags": [
          "Corporation Tax"
        ],
        "x-required-scopes": [
          "corporation_tax:read"
        ],
        "x-required-product": "corporation_tax"
      },
      "post": {
        "description": "Preparers and above, for limited companies. A period of account over 12 months makes one return per accounting period; this answers with the first, and `relatedReturns` names the rest. Accounting periods starting before 1 April 2023 are refused with 422. No Working Papers file or Accounts set is needed.\n\nNeeds the Preparer role or above. Scopes: `corporation_tax:write`. Part of the `corporation_tax` product: the firm must have it and you must have access to it.",
        "operationId": "CtReturns_create",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "A unique key (1-255 visible characters) to make retries safe. Replayed for 24 hours.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateCtReturnRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CtReturn"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "A request with this Idempotency-Key is still being processed.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "422": {
            "description": "This Idempotency-Key was already used for a different request.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "corporation_tax:write"
            ]
          }
        ],
        "summary": "Start a return",
        "tags": [
          "Corporation Tax"
        ],
        "x-required-role": "preparer",
        "x-required-scopes": [
          "corporation_tax:write"
        ],
        "x-required-product": "corporation_tax"
      }
    },
    "/api/v1/corporation-tax/returns/{id}": {
      "get": {
        "description": "The boxes, the computation, what would stop it being filed, where the figures came from, review points and history. `canFile` says whether anything blocks filing; `filingEnabled` whether filing is switched on. Bank details are only ever masked.\n\nScopes: `corporation_tax:read`. Part of the `corporation_tax` product: the firm must have it and you must have access to it.",
        "operationId": "CtReturns_get",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CtReturn"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "corporation_tax:read"
            ]
          }
        ],
        "summary": "Get a return",
        "tags": [
          "Corporation Tax"
        ],
        "x-required-scopes": [
          "corporation_tax:read"
        ],
        "x-required-product": "corporation_tax"
      },
      "patch": {
        "description": "Preparers and above. Figures are a new immutable version, shared by every return of the period of account. Any change takes a reviewed or approved return back to draft. Figures from a linked source are refused with 409; refused once it’s with HMRC.\n\nNeeds the Preparer role or above. Scopes: `corporation_tax:write`. Part of the `corporation_tax` product: the firm must have it and you must have access to it.",
        "operationId": "CtReturns_update",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateCtReturnRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CtReturn"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "corporation_tax:write"
            ]
          }
        ],
        "summary": "Change a return",
        "tags": [
          "Corporation Tax"
        ],
        "x-required-role": "preparer",
        "x-required-scopes": [
          "corporation_tax:write"
        ],
        "x-required-product": "corporation_tax"
      }
    },
    "/api/v1/corporation-tax/returns/{id}/group-relief": {
      "get": {
        "description": "Notices of consent touching this company, the companies its client record connects it with, and an associated company count from those links. The links are suggestions: nothing is applied, and the group test is what a person says.\n\nScopes: `corporation_tax:read`. Part of the `corporation_tax` product: the firm must have it and you must have access to it.",
        "operationId": "CtReturns_groupRelief",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CtGroupReliefState"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "corporation_tax:read"
            ]
          }
        ],
        "summary": "Group relief for a return",
        "tags": [
          "Corporation Tax"
        ],
        "x-required-scopes": [
          "corporation_tax:read"
        ],
        "x-required-product": "corporation_tax"
      }
    },
    "/api/v1/corporation-tax/returns/{id}/group-relief/notices": {
      "post": {
        "description": "Preparers and above. Records a notice given to HMRC, between this company and another client of the firm (FA 1998 Sch 18 para 70). A notice can’t be changed: withdraw it and record another. Recording it doesn’t change either return.\n\nNeeds the Preparer role or above. Scopes: `corporation_tax:write`. Part of the `corporation_tax` product: the firm must have it and you must have access to it.",
        "operationId": "CtReturns_createGroupNotice",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "A unique key (1-255 visible characters) to make retries safe. Replayed for 24 hours.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateCtGroupNoticeRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CtGroupNotice"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "A request with this Idempotency-Key is still being processed.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "422": {
            "description": "This Idempotency-Key was already used for a different request.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "corporation_tax:write"
            ]
          }
        ],
        "summary": "Record a notice of consent",
        "tags": [
          "Corporation Tax"
        ],
        "x-required-role": "preparer",
        "x-required-scopes": [
          "corporation_tax:write"
        ],
        "x-required-product": "corporation_tax"
      }
    },
    "/api/v1/corporation-tax/returns/{id}/group-relief/notices/{noticeId}/withdraw": {
      "post": {
        "description": "Preparers and above. A return that relies on it then can’t be filed until it’s replaced (FA 1998 Sch 18 para 71).\n\nNeeds the Preparer role or above. Scopes: `corporation_tax:write`. Part of the `corporation_tax` product: the firm must have it and you must have access to it.",
        "operationId": "CtReturns_withdrawGroupNotice",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "noticeId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "A unique key (1-255 visible characters) to make retries safe. Replayed for 24 hours.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CtGroupNotice"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "A request with this Idempotency-Key is still being processed.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "422": {
            "description": "This Idempotency-Key was already used for a different request.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "corporation_tax:write"
            ]
          }
        ],
        "summary": "Withdraw a notice of consent",
        "tags": [
          "Corporation Tax"
        ],
        "x-required-role": "preparer",
        "x-required-scopes": [
          "corporation_tax:write"
        ],
        "x-required-product": "corporation_tax"
      }
    },
    "/api/v1/corporation-tax/returns/{id}/sources/link": {
      "post": {
        "description": "Preparers and above. Snapshots a Working Papers file’s tax computation, or takes profit and turnover from an approved Accounts set, or attaches only the accounts. The source of the same client and period is never written to, and later changes to it are only flagged until someone refreshes. Needs read access to the source’s product.\n\nNeeds the Preparer role or above. Scopes: `corporation_tax:write`. Part of the `corporation_tax` product: the firm must have it and you must have access to it.",
        "operationId": "CtReturns_link",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LinkCtSourceRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CtReturn"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "corporation_tax:write"
            ]
          }
        ],
        "summary": "Link a source",
        "tags": [
          "Corporation Tax"
        ],
        "x-required-role": "preparer",
        "x-required-scopes": [
          "corporation_tax:write"
        ],
        "x-required-product": "corporation_tax"
      }
    },
    "/api/v1/corporation-tax/returns/{id}/sources/refresh": {
      "post": {
        "description": "Preparers and above. Brings in what a linked file or set now holds, as a new version. Nothing changes if they already match. A real change loses an approval.\n\nNeeds the Preparer role or above. Scopes: `corporation_tax:write`. Part of the `corporation_tax` product: the firm must have it and you must have access to it.",
        "operationId": "CtReturns_refresh",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CtReturn"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "corporation_tax:write"
            ]
          }
        ],
        "summary": "Refresh from the source",
        "tags": [
          "Corporation Tax"
        ],
        "x-required-role": "preparer",
        "x-required-scopes": [
          "corporation_tax:write"
        ],
        "x-required-product": "corporation_tax"
      }
    },
    "/api/v1/corporation-tax/returns/{id}/roll-forward": {
      "post": {
        "description": "Preparers and above. Carries trading losses, loans to participators, capital allowance pool balances and the answers from this return. This year’s figures start at nil.\n\nNeeds the Preparer role or above. Scopes: `corporation_tax:write`. Part of the `corporation_tax` product: the firm must have it and you must have access to it.",
        "operationId": "CtReturns_rollForward",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "A unique key (1-255 visible characters) to make retries safe. Replayed for 24 hours.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RollForwardCtReturnRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CtReturn"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "A request with this Idempotency-Key is still being processed.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "422": {
            "description": "This Idempotency-Key was already used for a different request.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "corporation_tax:write"
            ]
          }
        ],
        "summary": "Start next period’s return",
        "tags": [
          "Corporation Tax"
        ],
        "x-required-role": "preparer",
        "x-required-scopes": [
          "corporation_tax:write"
        ],
        "x-required-product": "corporation_tax"
      }
    },
    "/api/v1/corporation-tax/returns/{id}/send-for-review": {
      "post": {
        "description": "Preparers and above, from draft.\n\nNeeds the Preparer role or above. Scopes: `corporation_tax:write`. Part of the `corporation_tax` product: the firm must have it and you must have access to it.",
        "operationId": "CtReturns_sendForReview",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CtNoteRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CtReturn"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "corporation_tax:write"
            ]
          }
        ],
        "summary": "Send for review",
        "tags": [
          "Corporation Tax"
        ],
        "x-required-role": "preparer",
        "x-required-scopes": [
          "corporation_tax:write"
        ],
        "x-required-product": "corporation_tax"
      }
    },
    "/api/v1/corporation-tax/returns/{id}/review-points": {
      "post": {
        "description": "Reviewers and above. Open points stop a return being approved.\n\nNeeds the Reviewer role or above. Scopes: `review:write`. Part of the `corporation_tax` product: the firm must have it and you must have access to it.",
        "operationId": "CtReturns_raise",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RaiseCtReviewPointRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CtReturn"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "review:write"
            ]
          }
        ],
        "summary": "Raise a review point",
        "tags": [
          "Corporation Tax"
        ],
        "x-required-role": "reviewer",
        "x-required-scopes": [
          "review:write"
        ],
        "x-required-product": "corporation_tax"
      }
    },
    "/api/v1/corporation-tax/returns/{id}/review-points/{pointId}/clear": {
      "post": {
        "description": "Reviewers and above.\n\nNeeds the Reviewer role or above. Scopes: `review:write`. Part of the `corporation_tax` product: the firm must have it and you must have access to it.",
        "operationId": "CtReturns_clear",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "pointId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CtReturn"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "review:write"
            ]
          }
        ],
        "summary": "Clear a review point",
        "tags": [
          "Corporation Tax"
        ],
        "x-required-role": "reviewer",
        "x-required-scopes": [
          "review:write"
        ],
        "x-required-product": "corporation_tax"
      }
    },
    "/api/v1/corporation-tax/returns/{id}/approve": {
      "post": {
        "description": "A partner, signed in, or a manager where the firm allows it (403 otherwise). Refused with open review points, with a linked source changed, or if the figures moved since you reviewed them. What stops filing doesn’t stop approval. Never available to API keys or connected assistants.\n\nNeeds the Manager role or above. Scopes: `review:write`. Part of the `corporation_tax` product: the firm must have it and you must have access to it. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "CtReturns_approve",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ApproveCtReturnRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CtReturn"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Approve a return",
        "tags": [
          "Corporation Tax"
        ],
        "x-required-role": "manager",
        "x-required-scopes": [
          "review:write"
        ],
        "x-required-product": "corporation_tax",
        "x-session-only": true
      }
    },
    "/api/v1/corporation-tax/returns/{id}/reopen": {
      "post": {
        "description": "Reviewers and above, signed in. Back to draft, and an approval is lost. Never available to API keys or connected assistants.\n\nNeeds the Reviewer role or above. Scopes: `review:write`. Part of the `corporation_tax` product: the firm must have it and you must have access to it. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "CtReturns_reopen",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CtNoteRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CtReturn"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Reopen a return",
        "tags": [
          "Corporation Tax"
        ],
        "x-required-role": "reviewer",
        "x-required-scopes": [
          "review:write"
        ],
        "x-required-product": "corporation_tax",
        "x-session-only": true
      }
    },
    "/api/v1/corporation-tax/returns/{id}/amend": {
      "post": {
        "description": "Preparers and above, signed in. Only a filed return, within 12 months of its filing date (FA 1998 Sch 18 para 15(4)). A new draft with the filed figures: the original is never changed, and the amendment has its own review, approval and client's confirmation. Filing stays off. Never available to API keys or connected assistants.\n\nNeeds the Preparer role or above. Scopes: `corporation_tax:write`. Part of the `corporation_tax` product: the firm must have it and you must have access to it. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "CtReturns_amend",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CtNoteRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CtReturn"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Start an amended return",
        "tags": [
          "Corporation Tax"
        ],
        "x-required-role": "preparer",
        "x-required-scopes": [
          "corporation_tax:write"
        ],
        "x-required-product": "corporation_tax",
        "x-session-only": true
      }
    },
    "/api/v1/corporation-tax/returns/{id}/filed-elsewhere": {
      "post": {
        "description": "A partner, signed in, for an approved return that went to HMRC by other means. It's the partner's record, not HMRC's word, and nothing is sent. Never available to API keys or connected assistants.\n\nNeeds the Partner role or above. Scopes: `review:write`. Part of the `corporation_tax` product: the firm must have it and you must have access to it. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "CtReturns_filedElsewhere",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RecordCtFiledElsewhereRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CtReturn"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Record a return as filed outside Tolvi",
        "tags": [
          "Corporation Tax"
        ],
        "x-required-role": "partner",
        "x-required-scopes": [
          "review:write"
        ],
        "x-required-product": "corporation_tax",
        "x-session-only": true
      }
    },
    "/api/v1/corporation-tax/returns/{id}/client-confirmation": {
      "post": {
        "description": "Preparers and above, signed in. The client confirmed the copy they were sent. It counts only for these figures. Never available to API keys or connected assistants.\n\nNeeds the Preparer role or above. Scopes: `corporation_tax:write`. Part of the `corporation_tax` product: the firm must have it and you must have access to it. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "CtReturns_clientConfirmation",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RecordCtClientConfirmationRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CtReturn"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Record the client’s confirmation",
        "tags": [
          "Corporation Tax"
        ],
        "x-required-role": "preparer",
        "x-required-scopes": [
          "corporation_tax:write"
        ],
        "x-required-product": "corporation_tax",
        "x-session-only": true
      }
    },
    "/api/v1/corporation-tax/returns/{id}/submit": {
      "post": {
        "description": "A manager or partner, signed in with a second factor, once these figures are approved, the client has confirmed them and nothing blocks filing. Answers 503 until filing is switched on, once HMRC’s test service has passed. Never available to API keys or connected assistants.\n\nNeeds the Manager role or above. Scopes: `corporation_tax:write`. Part of the `corporation_tax` product: the firm must have it and you must have access to it. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "CtReturns_submit",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "A unique key (1-255 visible characters) to make retries safe. Replayed for 24 hours.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SubmitCtReturnRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CtReturn"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "A request with this Idempotency-Key is still being processed.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "422": {
            "description": "This Idempotency-Key was already used for a different request.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "File with HMRC",
        "tags": [
          "Corporation Tax"
        ],
        "x-required-role": "manager",
        "x-required-scopes": [
          "corporation_tax:write"
        ],
        "x-required-product": "corporation_tax",
        "x-session-only": true
      }
    },
    "/api/v1/corporation-tax/returns/{id}/submissions/{submissionId}/poll": {
      "post": {
        "description": "While HMRC is checking a return. Tolvi also asks by itself.\n\nScopes: `corporation_tax:read`. Part of the `corporation_tax` product: the firm must have it and you must have access to it.",
        "operationId": "CtReturns_poll",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "submissionId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CtReturn"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "corporation_tax:read"
            ]
          }
        ],
        "summary": "Ask HMRC for its answer",
        "tags": [
          "Corporation Tax"
        ],
        "x-required-scopes": [
          "corporation_tax:read"
        ],
        "x-required-product": "corporation_tax"
      }
    },
    "/api/v1/corporation-tax/returns/{id}/downloads/ct600.pdf": {
      "get": {
        "description": "The return in the style of HMRC’s form, with CT600A where it applies. Every page gives its status and says it wasn’t issued by HMRC. Bank details appear masked.\n\nScopes: `corporation_tax:read`. Part of the `corporation_tax` product: the firm must have it and you must have access to it.",
        "operationId": "CtReturns_ct600",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A PDF.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "corporation_tax:read"
            ]
          }
        ],
        "summary": "Download the CT600",
        "tags": [
          "Corporation Tax"
        ],
        "x-required-scopes": [
          "corporation_tax:read"
        ],
        "x-required-product": "corporation_tax"
      }
    },
    "/api/v1/corporation-tax/returns/{id}/downloads/computation.pdf": {
      "get": {
        "description": "The tax computation for this accounting period, for people to read.\n\nScopes: `corporation_tax:read`. Part of the `corporation_tax` product: the firm must have it and you must have access to it.",
        "operationId": "CtReturns_computationPdf",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A PDF.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "corporation_tax:read"
            ]
          }
        ],
        "summary": "Download the computation",
        "tags": [
          "Corporation Tax"
        ],
        "x-required-scopes": [
          "corporation_tax:read"
        ],
        "x-required-product": "corporation_tax"
      }
    },
    "/api/v1/corporation-tax/returns/{id}/downloads/accounts.xhtml": {
      "get": {
        "description": "The tagged accounts from the linked Accounts set. 409 with no set linked. What stops the file being filed is in the return’s `problems`.\n\nScopes: `corporation_tax:read`. Part of the `corporation_tax` product: the firm must have it and you must have access to it.",
        "operationId": "CtReturns_accountsIxbrl",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "iXBRL.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "corporation_tax:read"
            ]
          }
        ],
        "summary": "Download the iXBRL accounts",
        "tags": [
          "Corporation Tax"
        ],
        "x-required-scopes": [
          "corporation_tax:read"
        ],
        "x-required-product": "corporation_tax"
      }
    },
    "/api/v1/corporation-tax/returns/{id}/downloads/computation.xhtml": {
      "get": {
        "description": "The tagged computation for this accounting period. What stops the file being filed is in the return’s `problems`.\n\nScopes: `corporation_tax:read`. Part of the `corporation_tax` product: the firm must have it and you must have access to it.",
        "operationId": "CtReturns_computationIxbrl",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "iXBRL.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "corporation_tax:read"
            ]
          }
        ],
        "summary": "Download the iXBRL computation",
        "tags": [
          "Corporation Tax"
        ],
        "x-required-scopes": [
          "corporation_tax:read"
        ],
        "x-required-product": "corporation_tax"
      }
    },
    "/api/v1/corporation-tax/returns/{id}/downloads/ct600.xml": {
      "get": {
        "description": "The return in the order of HMRC’s schema, as it would be sent, without any sign-in and with bank details masked. It isn’t filed by downloading it.\n\nScopes: `corporation_tax:read`. Part of the `corporation_tax` product: the firm must have it and you must have access to it.",
        "operationId": "CtReturns_xml",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "XML.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "corporation_tax:read"
            ]
          }
        ],
        "summary": "Preview the CT600 XML",
        "tags": [
          "Corporation Tax"
        ],
        "x-required-scopes": [
          "corporation_tax:read"
        ],
        "x-required-product": "corporation_tax"
      }
    },
    "/api/v1/corporation-tax/agent-accounts": {
      "get": {
        "description": "Names and status only: a saved sign-in is never returned.\n\nScopes: `corporation_tax:read`. Part of the `corporation_tax` product: the firm must have it and you must have access to it.",
        "operationId": "CtAgentAccounts_list",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CtAgentAccountList"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "corporation_tax:read"
            ]
          }
        ],
        "summary": "List HMRC accounts",
        "tags": [
          "Corporation Tax"
        ],
        "x-required-scopes": [
          "corporation_tax:read"
        ],
        "x-required-product": "corporation_tax"
      },
      "post": {
        "description": "Firm admins, signed in. Name it so people can tell them apart, such as Leeds office.\n\nScopes: `settings:admin`. Part of the `corporation_tax` product: the firm must have it and you must have access to it. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "CtAgentAccounts_create",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateCtAgentAccountRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CtAgentAccount"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Add an HMRC account",
        "tags": [
          "Corporation Tax"
        ],
        "x-required-scopes": [
          "settings:admin"
        ],
        "x-required-product": "corporation_tax",
        "x-session-only": true
      }
    },
    "/api/v1/corporation-tax/agent-accounts/{id}": {
      "delete": {
        "description": "Firm admins, signed in. Its sign-in is deleted at once.\n\nScopes: `settings:admin`. Part of the `corporation_tax` product: the firm must have it and you must have access to it. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "CtAgentAccounts_remove",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Remove an HMRC account",
        "tags": [
          "Corporation Tax"
        ],
        "x-required-scopes": [
          "settings:admin"
        ],
        "x-required-product": "corporation_tax",
        "x-session-only": true
      }
    },
    "/api/v1/corporation-tax/agent-accounts/{id}/credentials": {
      "put": {
        "description": "Firm admins, signed in. Encrypted, used only when someone allowed to file files a return, and never shown again.\n\nScopes: `settings:admin`. Part of the `corporation_tax` product: the firm must have it and you must have access to it. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "CtAgentAccounts_save",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SaveCtCredentialsRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CtAgentAccount"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Save the HMRC sign-in",
        "tags": [
          "Corporation Tax"
        ],
        "x-required-scopes": [
          "settings:admin"
        ],
        "x-required-product": "corporation_tax",
        "x-session-only": true
      },
      "delete": {
        "description": "Firm admins, signed in.\n\nScopes: `settings:admin`. Part of the `corporation_tax` product: the firm must have it and you must have access to it. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "CtAgentAccounts_removeCredentials",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CtAgentAccount"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Delete the saved sign-in",
        "tags": [
          "Corporation Tax"
        ],
        "x-required-scopes": [
          "settings:admin"
        ],
        "x-required-product": "corporation_tax",
        "x-session-only": true
      }
    },
    "/api/v1/self-assessment/returns": {
      "get": {
        "description": "Every client’s return, with its status and how long is left. Filter by client, tax year or status.\n\nScopes: `self_assessment:read`. Part of the `self_assessment` product: the firm must have it and you must have access to it.",
        "operationId": "SaReturns_list",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "status",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "taxYearEnd",
            "required": false,
            "in": "query",
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "clientId",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SaReturnList"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "self_assessment:read"
            ]
          }
        ],
        "summary": "List returns",
        "tags": [
          "Self Assessment"
        ],
        "x-required-scopes": [
          "self_assessment:read"
        ],
        "x-required-product": "self_assessment"
      },
      "post": {
        "description": "Preparers and above. One of each form per client and tax year: an SA100, an SA800 or an SA900. Last year’s details carry forward, and on an SA900 the tax pool.\n\nNeeds the Preparer role or above. Scopes: `self_assessment:write`. Part of the `self_assessment` product: the firm must have it and you must have access to it.",
        "operationId": "SaReturns_create",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "A unique key (1-255 visible characters) to make retries safe. Replayed for 24 hours.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateSaReturnRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SaReturn"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "A request with this Idempotency-Key is still being processed.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "422": {
            "description": "This Idempotency-Key was already used for a different request.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "self_assessment:write"
            ]
          }
        ],
        "summary": "Start a return",
        "tags": [
          "Self Assessment"
        ],
        "x-required-role": "preparer",
        "x-required-scopes": [
          "self_assessment:write"
        ],
        "x-required-product": "self_assessment"
      }
    },
    "/api/v1/self-assessment/returns/{id}": {
      "get": {
        "description": "The boxes and where each came from, HMRC’s calculation for them, what HMRC’s rules would refuse, review points and history. The National Insurance number, date of birth and bank details are only ever masked.\n\nScopes: `self_assessment:read`. Part of the `self_assessment` product: the firm must have it and you must have access to it.",
        "operationId": "SaReturns_get",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SaReturn"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "self_assessment:read"
            ]
          }
        ],
        "summary": "Get a return",
        "tags": [
          "Self Assessment"
        ],
        "x-required-scopes": [
          "self_assessment:read"
        ],
        "x-required-product": "self_assessment"
      },
      "patch": {
        "description": "Preparers and above. Changing an approved or reviewed return takes it back to draft. Refused once it’s with HMRC.\n\nNeeds the Preparer role or above. Scopes: `self_assessment:write`. Part of the `self_assessment` product: the firm must have it and you must have access to it.",
        "operationId": "SaReturns_update",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateSaReturnRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SaReturn"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "self_assessment:write"
            ]
          }
        ],
        "summary": "Change a return",
        "tags": [
          "Self Assessment"
        ],
        "x-required-role": "preparer",
        "x-required-scopes": [
          "self_assessment:write"
        ],
        "x-required-product": "self_assessment"
      }
    },
    "/api/v1/self-assessment/returns/{id}/plan": {
      "get": {
        "description": "The questions that decide which pages and boxes a return needs, the answers so far, and the steps they lead to. Used by Simple Step and AI Mode alike.\n\nScopes: `self_assessment:read`. Part of the `self_assessment` product: the firm must have it and you must have access to it.",
        "operationId": "SaReturns_plan",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SaPlan"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "self_assessment:read"
            ]
          }
        ],
        "summary": "Get what a return needs",
        "tags": [
          "Self Assessment"
        ],
        "x-required-scopes": [
          "self_assessment:read"
        ],
        "x-required-product": "self_assessment"
      },
      "put": {
        "description": "Preparers and above. Saves answers and brings the pages into line. Pages with figures are never removed: they’re listed in `extraPages` for a person to decide.\n\nNeeds the Preparer role or above. Scopes: `self_assessment:write`. Part of the `self_assessment` product: the firm must have it and you must have access to it.",
        "operationId": "SaReturns_answer",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SaveSaAnswersRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SaPlan"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "self_assessment:write"
            ]
          }
        ],
        "summary": "Answer what a return needs",
        "tags": [
          "Self Assessment"
        ],
        "x-required-role": "preparer",
        "x-required-scopes": [
          "self_assessment:write"
        ],
        "x-required-product": "self_assessment"
      }
    },
    "/api/v1/self-assessment/returns/{id}/pdf": {
      "get": {
        "description": "Every page of the return in the style of HMRC’s forms, then the calculation, as a PDF: to send the client for their approval, or to file another way until Tolvi can. Sensitive boxes appear masked.\n\nScopes: `self_assessment:read`. Part of the `self_assessment` product: the firm must have it and you must have access to it.",
        "operationId": "SaReturns_pdf",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A PDF.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "self_assessment:read"
            ]
          }
        ],
        "summary": "Download the full return",
        "tags": [
          "Self Assessment"
        ],
        "x-required-scopes": [
          "self_assessment:read"
        ],
        "x-required-product": "self_assessment"
      }
    },
    "/api/v1/self-assessment/returns/{id}/sa302": {
      "get": {
        "description": "The tax calculation alone, in the order of HMRC’s SA302, as a PDF. Prepared from the return’s figures, and says how far the return has got; not issued by HMRC.\n\nScopes: `self_assessment:read`. Part of the `self_assessment` product: the firm must have it and you must have access to it.",
        "operationId": "SaReturns_sa302",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A PDF.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "self_assessment:read"
            ]
          }
        ],
        "summary": "Download the SA302",
        "tags": [
          "Self Assessment"
        ],
        "x-required-scopes": [
          "self_assessment:read"
        ],
        "x-required-product": "self_assessment"
      }
    },
    "/api/v1/self-assessment/returns/{id}/partners": {
      "put": {
        "description": "Who shares the partnership statement and how. The statement’s figures are allocated to them, and a partner with a client record here is offered their SA104 as a suggestion on their own SA100. Changing an approved return takes it back to draft.\n\nNeeds the Preparer role or above. Scopes: `self_assessment:write`. Part of the `self_assessment` product: the firm must have it and you must have access to it.",
        "operationId": "SaReturns_setPartners",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SetSaPartnersRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SaReturn"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "self_assessment:write"
            ]
          }
        ],
        "summary": "Set the partners on an SA800",
        "tags": [
          "Self Assessment"
        ],
        "x-required-role": "preparer",
        "x-required-scopes": [
          "self_assessment:write"
        ],
        "x-required-product": "self_assessment"
      }
    },
    "/api/v1/self-assessment/returns/{id}/r185": {
      "post": {
        "description": "A statement for a beneficiary of a trust or estate, worked from the SA900, as a PDF. A person checks and signs it; it isn’t filed and isn’t kept. Trust management expenses aren’t taken off: send your own figures in `overrides`. Not issued by HMRC.\n\nScopes: `self_assessment:read`. Part of the `self_assessment` product: the firm must have it and you must have access to it.",
        "operationId": "SaReturns_r185",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MakeR185Request"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "A PDF.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "self_assessment:read"
            ]
          }
        ],
        "summary": "Download an R185",
        "tags": [
          "Self Assessment"
        ],
        "x-required-scopes": [
          "self_assessment:read"
        ],
        "x-required-product": "self_assessment"
      }
    },
    "/api/v1/self-assessment/returns/{id}/import/working-papers": {
      "post": {
        "description": "Fills the SA103 from a sole trader’s section T in Working Papers. Answers such as dates stay for a person to give.\n\nNeeds the Preparer role or above. Scopes: `self_assessment:write`. Part of the `self_assessment` product: the firm must have it and you must have access to it.",
        "operationId": "SaReturns_importWp",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ImportSaFromWorkingPapersRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SaReturn"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "self_assessment:write"
            ]
          }
        ],
        "summary": "Bring in section T",
        "tags": [
          "Self Assessment"
        ],
        "x-required-role": "preparer",
        "x-required-scopes": [
          "self_assessment:write"
        ],
        "x-required-product": "self_assessment"
      }
    },
    "/api/v1/self-assessment/returns/{id}/hmrc-data": {
      "get": {
        "description": "As last fetched: figures you can apply, and the Self Assessment account.\n\nScopes: `self_assessment:read`. Part of the `self_assessment` product: the firm must have it and you must have access to it.",
        "operationId": "SaReturns_hmrcData",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SaHmrcData"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "self_assessment:read"
            ]
          }
        ],
        "summary": "See what HMRC holds",
        "tags": [
          "Self Assessment"
        ],
        "x-required-scopes": [
          "self_assessment:read"
        ],
        "x-required-product": "self_assessment"
      }
    },
    "/api/v1/self-assessment/returns/{id}/hmrc-data/refresh": {
      "post": {
        "description": "Preparers and above, with a connected HMRC account authorised for this client.\n\nNeeds the Preparer role or above. Scopes: `self_assessment:write`. Part of the `self_assessment` product: the firm must have it and you must have access to it.",
        "operationId": "SaReturns_refresh",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RefreshSaHmrcDataRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SaHmrcData"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "self_assessment:write"
            ]
          }
        ],
        "summary": "Ask HMRC what it holds",
        "tags": [
          "Self Assessment"
        ],
        "x-required-role": "preparer",
        "x-required-scopes": [
          "self_assessment:write"
        ],
        "x-required-product": "self_assessment"
      }
    },
    "/api/v1/self-assessment/returns/{id}/hmrc-data/apply": {
      "post": {
        "description": "The figures you choose. An SA102 is added for an employer the return doesn’t have.\n\nNeeds the Preparer role or above. Scopes: `self_assessment:write`. Part of the `self_assessment` product: the firm must have it and you must have access to it.",
        "operationId": "SaReturns_apply",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ApplySaHmrcDataRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SaReturn"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "self_assessment:write"
            ]
          }
        ],
        "summary": "Put HMRC’s figures on the return",
        "tags": [
          "Self Assessment"
        ],
        "x-required-role": "preparer",
        "x-required-scopes": [
          "self_assessment:write"
        ],
        "x-required-product": "self_assessment"
      }
    },
    "/api/v1/self-assessment/returns/{id}/send-for-review": {
      "post": {
        "description": "Preparers and above, from draft.\n\nNeeds the Preparer role or above. Scopes: `self_assessment:write`. Part of the `self_assessment` product: the firm must have it and you must have access to it.",
        "operationId": "SaReturns_sendForReview",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SaNoteRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SaReturn"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "self_assessment:write"
            ]
          }
        ],
        "summary": "Send for review",
        "tags": [
          "Self Assessment"
        ],
        "x-required-role": "preparer",
        "x-required-scopes": [
          "self_assessment:write"
        ],
        "x-required-product": "self_assessment"
      }
    },
    "/api/v1/self-assessment/returns/{id}/return-to-draft": {
      "post": {
        "description": "Reviewers and above. An approval is lost.\n\nNeeds the Reviewer role or above. Scopes: `review:write`. Part of the `self_assessment` product: the firm must have it and you must have access to it.",
        "operationId": "SaReturns_backToDraft",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SaNoteRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SaReturn"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "review:write"
            ]
          }
        ],
        "summary": "Return to draft",
        "tags": [
          "Self Assessment"
        ],
        "x-required-role": "reviewer",
        "x-required-scopes": [
          "review:write"
        ],
        "x-required-product": "self_assessment"
      }
    },
    "/api/v1/self-assessment/returns/{id}/review-points": {
      "post": {
        "description": "Reviewers and above. Open points stop a return being approved.\n\nNeeds the Reviewer role or above. Scopes: `review:write`. Part of the `self_assessment` product: the firm must have it and you must have access to it.",
        "operationId": "SaReturns_raise",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RaiseSaReviewPointRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SaReturn"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "review:write"
            ]
          }
        ],
        "summary": "Raise a review point",
        "tags": [
          "Self Assessment"
        ],
        "x-required-role": "reviewer",
        "x-required-scopes": [
          "review:write"
        ],
        "x-required-product": "self_assessment"
      }
    },
    "/api/v1/self-assessment/returns/{id}/review-points/{pointId}/clear": {
      "post": {
        "description": "Reviewers and above.\n\nNeeds the Reviewer role or above. Scopes: `review:write`. Part of the `self_assessment` product: the firm must have it and you must have access to it.",
        "operationId": "SaReturns_clear",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "pointId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SaReturn"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "review:write"
            ]
          }
        ],
        "summary": "Clear a review point",
        "tags": [
          "Self Assessment"
        ],
        "x-required-role": "reviewer",
        "x-required-scopes": [
          "review:write"
        ],
        "x-required-product": "self_assessment"
      }
    },
    "/api/v1/self-assessment/returns/{id}/approve": {
      "post": {
        "description": "A partner, signed in, or a manager where the firm allows it (403 otherwise). Refused with open review points, with anything HMRC’s rules would refuse, or if the figures moved since you reviewed them. Never available to connected assistants.\n\nNeeds the Manager role or above. Scopes: `review:write`. Part of the `self_assessment` product: the firm must have it and you must have access to it. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "SaReturns_approve",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ApproveSaReturnRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SaReturn"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Approve a return",
        "tags": [
          "Self Assessment"
        ],
        "x-required-role": "manager",
        "x-required-scopes": [
          "review:write"
        ],
        "x-required-product": "self_assessment",
        "x-session-only": true
      }
    },
    "/api/v1/self-assessment/returns/{id}/client-approval": {
      "post": {
        "description": "HMRC requires the client to confirm in writing the copy they were sent. Applies only to these figures. Never available to connected assistants.\n\nNeeds the Preparer role or above. Scopes: `self_assessment:write`. Part of the `self_assessment` product: the firm must have it and you must have access to it. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "SaReturns_clientApproval",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RecordSaClientApprovalRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SaReturn"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Record the client’s approval",
        "tags": [
          "Self Assessment"
        ],
        "x-required-role": "preparer",
        "x-required-scopes": [
          "self_assessment:write"
        ],
        "x-required-product": "self_assessment",
        "x-session-only": true
      }
    },
    "/api/v1/self-assessment/returns/{id}/submit": {
      "post": {
        "description": "A manager or partner, signed in with a second factor, once these figures are approved and the client has confirmed them. Answers 503 until filing is switched on, once HMRC has approved Tolvi. Never available to connected assistants.\n\nNeeds the Manager role or above. Scopes: `self_assessment:write`. Part of the `self_assessment` product: the firm must have it and you must have access to it. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "SaReturns_submit",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "A unique key (1-255 visible characters) to make retries safe. Replayed for 24 hours.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SubmitSaReturnRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SaReturn"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "A request with this Idempotency-Key is still being processed.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "422": {
            "description": "This Idempotency-Key was already used for a different request.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "File with HMRC",
        "tags": [
          "Self Assessment"
        ],
        "x-required-role": "manager",
        "x-required-scopes": [
          "self_assessment:write"
        ],
        "x-required-product": "self_assessment",
        "x-session-only": true
      }
    },
    "/api/v1/self-assessment/returns/{id}/submissions/{submissionId}/poll": {
      "post": {
        "description": "While HMRC is checking a return. Tolvi also asks by itself.\n\nScopes: `self_assessment:read`. Part of the `self_assessment` product: the firm must have it and you must have access to it.",
        "operationId": "SaReturns_poll",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "submissionId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SaReturn"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "self_assessment:read"
            ]
          }
        ],
        "summary": "Ask HMRC for its answer",
        "tags": [
          "Self Assessment"
        ],
        "x-required-scopes": [
          "self_assessment:read"
        ],
        "x-required-product": "self_assessment"
      }
    },
    "/api/v1/self-assessment/returns/{id}/ai": {
      "get": {
        "description": "The conversation, the documents, the plan, and about what the next turn would cost. Not available to connected assistants.\n\nScopes: `self_assessment:read`. Part of the `self_assessment` product: the firm must have it and you must have access to it.",
        "operationId": "SaAi_state",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SaAiState"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "self_assessment:read"
            ]
          }
        ],
        "summary": "Get AI Mode on a return",
        "tags": [
          "Self Assessment"
        ],
        "x-required-scopes": [
          "self_assessment:read"
        ],
        "x-required-product": "self_assessment"
      }
    },
    "/api/v1/self-assessment/returns/{id}/ai/messages": {
      "post": {
        "description": "Preparers and above, on a draft. Spends the firm’s Tolvi AI tokens. Any figure it changes is read by Tolvi from the evidence it cites, and goes back to needing a person’s check. Refused figures are returned with the reason.\n\nNeeds the Preparer role or above. Scopes: `self_assessment:write`. Part of the `self_assessment` product: the firm must have it and you must have access to it. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "SaAi_message",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SendSaAiMessageRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SaAiTurn"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Tell or ask AI Mode",
        "tags": [
          "Self Assessment"
        ],
        "x-required-role": "preparer",
        "x-required-scopes": [
          "self_assessment:write"
        ],
        "x-required-product": "self_assessment",
        "x-session-only": true
      }
    },
    "/api/v1/self-assessment/returns/{id}/ai/complete": {
      "post": {
        "description": "Preparers and above, on a draft, once the questions are answered. Spends the firm’s Tolvi AI tokens. It fills only what the evidence supports. A person then checks each figure.\n\nNeeds the Preparer role or above. Scopes: `self_assessment:write`. Part of the `self_assessment` product: the firm must have it and you must have access to it. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "SaAi_complete",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SaAiTurn"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Have AI Mode fill the boxes",
        "tags": [
          "Self Assessment"
        ],
        "x-required-role": "preparer",
        "x-required-scopes": [
          "self_assessment:write"
        ],
        "x-required-product": "self_assessment",
        "x-session-only": true
      }
    },
    "/api/v1/self-assessment/returns/{id}/ai/confirm": {
      "post": {
        "description": "Preparers and above, signed in. Records who checked each figure. Doesn’t change the figures or approve anything. Never available to connected assistants.\n\nNeeds the Preparer role or above. Scopes: `self_assessment:write`. Part of the `self_assessment` product: the firm must have it and you must have access to it. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "SaAi_confirm",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ConfirmSaAiFiguresRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SaReturn"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Confirm figures AI filled",
        "tags": [
          "Self Assessment"
        ],
        "x-required-role": "preparer",
        "x-required-scopes": [
          "self_assessment:write"
        ],
        "x-required-product": "self_assessment",
        "x-session-only": true
      }
    },
    "/api/v1/self-assessment/returns/{id}/documents": {
      "post": {
        "description": "A PDF or photo, such as a P60. Returns where to upload it. Nothing reads it until the malware scan is clean.\n\nNeeds the Preparer role or above. Scopes: `self_assessment:write`. Part of the `self_assessment` product: the firm must have it and you must have access to it. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "SaAi_addDocument",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateSaDocumentRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SaDocumentUpload"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Add a document for AI Mode",
        "tags": [
          "Self Assessment"
        ],
        "x-required-role": "preparer",
        "x-required-scopes": [
          "self_assessment:write"
        ],
        "x-required-product": "self_assessment",
        "x-session-only": true
      }
    },
    "/api/v1/self-assessment/returns/{id}/documents/{documentId}/complete": {
      "post": {
        "description": "Checks the stored file and starts the malware scan.\n\nNeeds the Preparer role or above. Scopes: `self_assessment:write`. Part of the `self_assessment` product: the firm must have it and you must have access to it. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "SaAi_documentUploaded",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "documentId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SaDocument"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Finish uploading a document",
        "tags": [
          "Self Assessment"
        ],
        "x-required-role": "preparer",
        "x-required-scopes": [
          "self_assessment:write"
        ],
        "x-required-product": "self_assessment",
        "x-session-only": true
      }
    },
    "/api/v1/self-assessment/returns/{id}/documents/{documentId}/read": {
      "post": {
        "description": "Spends the firm’s Tolvi AI tokens. Refused until the malware scan is clean.\n\nNeeds the Preparer role or above. Scopes: `self_assessment:write`. Part of the `self_assessment` product: the firm must have it and you must have access to it. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "SaAi_readDocument",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "documentId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SaDocument"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Have AI Mode read a document",
        "tags": [
          "Self Assessment"
        ],
        "x-required-role": "preparer",
        "x-required-scopes": [
          "self_assessment:write"
        ],
        "x-required-product": "self_assessment",
        "x-session-only": true
      }
    },
    "/api/v1/self-assessment/returns/{id}/documents/{documentId}/download": {
      "get": {
        "description": "Refused until the malware scan is clean.\n\nScopes: `self_assessment:read`. Part of the `self_assessment` product: the firm must have it and you must have access to it.",
        "operationId": "SaAi_download",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "documentId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "url": {
                      "type": "string"
                    },
                    "expiresAt": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "url",
                    "expiresAt"
                  ]
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "self_assessment:read"
            ]
          }
        ],
        "summary": "Get a link to a document",
        "tags": [
          "Self Assessment"
        ],
        "x-required-scopes": [
          "self_assessment:read"
        ],
        "x-required-product": "self_assessment"
      }
    },
    "/api/v1/self-assessment/returns/{id}/documents/{documentId}": {
      "delete": {
        "description": "Deletes the file. Figures already taken from it stay on the return with the record of where they came from.\n\nNeeds the Preparer role or above. Scopes: `self_assessment:write`. Part of the `self_assessment` product: the firm must have it and you must have access to it. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "SaAi_removeDocument",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "documentId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Remove a document",
        "tags": [
          "Self Assessment"
        ],
        "x-required-role": "preparer",
        "x-required-scopes": [
          "self_assessment:write"
        ],
        "x-required-product": "self_assessment",
        "x-session-only": true
      }
    },
    "/api/v1/self-assessment/agent-accounts": {
      "get": {
        "description": "Names and status only: a saved sign-in is never returned.\n\nScopes: `self_assessment:read`. Part of the `self_assessment` product: the firm must have it and you must have access to it.",
        "operationId": "SaAgentAccounts_list",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SaAgentAccountList"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "self_assessment:read"
            ]
          }
        ],
        "summary": "List HMRC accounts",
        "tags": [
          "Self Assessment"
        ],
        "x-required-scopes": [
          "self_assessment:read"
        ],
        "x-required-product": "self_assessment"
      },
      "post": {
        "description": "Firm admins, signed in. Name it so people can tell them apart, such as Leeds office.\n\nScopes: `settings:admin`. Part of the `self_assessment` product: the firm must have it and you must have access to it. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "SaAgentAccounts_create",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateSaAgentAccountRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SaAgentAccount"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Add an HMRC account",
        "tags": [
          "Self Assessment"
        ],
        "x-required-scopes": [
          "settings:admin"
        ],
        "x-required-product": "self_assessment",
        "x-session-only": true
      }
    },
    "/api/v1/self-assessment/agent-accounts/{id}": {
      "patch": {
        "description": "Firm admins, signed in.\n\nScopes: `settings:admin`. Part of the `self_assessment` product: the firm must have it and you must have access to it. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "SaAgentAccounts_rename",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateSaAgentAccountRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SaAgentAccount"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Rename an HMRC account",
        "tags": [
          "Self Assessment"
        ],
        "x-required-scopes": [
          "settings:admin"
        ],
        "x-required-product": "self_assessment",
        "x-session-only": true
      },
      "delete": {
        "description": "Firm admins, signed in. Its sign-in and HMRC’s grant are deleted at once.\n\nScopes: `settings:admin`. Part of the `self_assessment` product: the firm must have it and you must have access to it. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "SaAgentAccounts_remove",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Remove an HMRC account",
        "tags": [
          "Self Assessment"
        ],
        "x-required-scopes": [
          "settings:admin"
        ],
        "x-required-product": "self_assessment",
        "x-session-only": true
      }
    },
    "/api/v1/self-assessment/agent-accounts/{id}/credentials": {
      "put": {
        "description": "Firm admins, signed in. Encrypted, used only when someone allowed to file files a return, and never shown again.\n\nScopes: `settings:admin`. Part of the `self_assessment` product: the firm must have it and you must have access to it. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "SaAgentAccounts_save",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SaveSaCredentialsRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SaAgentAccount"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Save the HMRC sign-in",
        "tags": [
          "Self Assessment"
        ],
        "x-required-scopes": [
          "settings:admin"
        ],
        "x-required-product": "self_assessment",
        "x-session-only": true
      },
      "delete": {
        "description": "Firm admins, signed in.\n\nScopes: `settings:admin`. Part of the `self_assessment` product: the firm must have it and you must have access to it. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "SaAgentAccounts_removeCredentials",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SaAgentAccount"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Delete the saved sign-in",
        "tags": [
          "Self Assessment"
        ],
        "x-required-scopes": [
          "settings:admin"
        ],
        "x-required-product": "self_assessment",
        "x-session-only": true
      }
    },
    "/api/v1/self-assessment/agent-accounts/{id}/authorize": {
      "post": {
        "description": "Firm admins, signed in. Gives the address where the account’s holder signs in at HMRC, to let Tolvi read its clients’ data for 18 months.\n\nScopes: `settings:admin`. Part of the `self_assessment` product: the firm must have it and you must have access to it. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "SaAgentAccounts_authorize",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SaAuthorizeUrl"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Connect to HMRC",
        "tags": [
          "Self Assessment"
        ],
        "x-required-scopes": [
          "settings:admin"
        ],
        "x-required-product": "self_assessment",
        "x-session-only": true
      }
    },
    "/api/v1/self-assessment/agent-accounts/callback": {
      "post": {
        "description": "Posted by the page HMRC sends people back to, as the person who started.\n\nScopes: `settings:admin`. Part of the `self_assessment` product: the firm must have it and you must have access to it. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "SaAgentAccounts_callback",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SaHmrcCallbackRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SaAgentAccount"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Finish connecting to HMRC",
        "tags": [
          "Self Assessment"
        ],
        "x-required-scopes": [
          "settings:admin"
        ],
        "x-required-product": "self_assessment",
        "x-session-only": true
      }
    },
    "/api/v1/self-assessment/agent-accounts/{id}/connection": {
      "delete": {
        "description": "Firm admins, signed in.\n\nScopes: `settings:admin`. Part of the `self_assessment` product: the firm must have it and you must have access to it. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "SaAgentAccounts_disconnect",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SaAgentAccount"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Disconnect from HMRC",
        "tags": [
          "Self Assessment"
        ],
        "x-required-scopes": [
          "settings:admin"
        ],
        "x-required-product": "self_assessment",
        "x-session-only": true
      }
    },
    "/api/v1/filing-batches/ready": {
      "get": {
        "description": "Self Assessment returns, Company Tax Returns and Companies House accounts approved in your products. Where a product’s filing is off, the row says it opens soon. Never available to API keys or connected assistants.\n\nNeeds the Manager role or above. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "FilingQueue_ready",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FilingReadyList"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "What could be filed",
        "tags": [
          "Filing queue"
        ],
        "x-required-role": "manager",
        "x-session-only": true
      }
    },
    "/api/v1/filing-batches": {
      "get": {
        "description": "Never available to API keys or connected assistants.\n\nNeeds the Manager role or above. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "FilingQueue_list",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FilingBatchList"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List batches",
        "tags": [
          "Filing queue"
        ],
        "x-required-role": "manager",
        "x-session-only": true
      },
      "post": {
        "description": "Nothing is sent. Answers 503 while batch filing or any chosen product’s filing is off. Off by default. It has only run against a fake: HMRC has not reviewed or accepted any of it. Never available to API keys or connected assistants.\n\nNeeds the Manager role or above. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "FilingQueue_create",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateFilingBatch"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FilingBatch"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Build a batch",
        "tags": [
          "Filing queue"
        ],
        "x-required-role": "manager",
        "x-session-only": true
      }
    },
    "/api/v1/filing-batches/{id}": {
      "get": {
        "description": "Never available to API keys or connected assistants.\n\nNeeds the Manager role or above. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "FilingQueue_get",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FilingBatch"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "A batch and each return’s status",
        "tags": [
          "Filing queue"
        ],
        "x-required-role": "manager",
        "x-session-only": true
      }
    },
    "/api/v1/filing-batches/{id}/start": {
      "post": {
        "description": "A manager or partner with a second factor. Each return goes through its own product’s filing, one at a time, with every control that has. A refusal stops that return and not the rest. Off by default. It has only run against a fake: HMRC has not reviewed or accepted any of it. Never available to API keys or connected assistants.\n\nNeeds the Manager role or above. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "FilingQueue_start",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "A unique key (1-255 visible characters) to make retries safe. Replayed for 24 hours.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/StartFilingBatch"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FilingBatch"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "A request with this Idempotency-Key is still being processed.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "422": {
            "description": "This Idempotency-Key was already used for a different request.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Start a batch",
        "tags": [
          "Filing queue"
        ],
        "x-required-role": "manager",
        "x-session-only": true
      }
    },
    "/api/v1/practice-vat/returns": {
      "get": {
        "operationId": "PracticeVat_list",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "clientId",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PracticeVatReturnList"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "self_assessment:read"
            ]
          }
        ],
        "summary": "List clients’ VAT returns",
        "tags": [
          "Practice VAT"
        ],
        "x-required-scopes": [
          "self_assessment:read"
        ],
        "x-required-product": "self_assessment",
        "description": "Scopes: `self_assessment:read`. Part of the `self_assessment` product: the firm must have it and you must have access to it."
      },
      "post": {
        "description": "From a bridging sheet, or nine boxes typed or carried from Working Papers or Books and labelled so.\n\nNeeds the Preparer role or above. Scopes: `self_assessment:write`. Part of the `self_assessment` product: the firm must have it and you must have access to it.",
        "operationId": "PracticeVat_create",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreatePracticeVatReturn"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PracticeVatReturn"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "self_assessment:write"
            ]
          }
        ],
        "summary": "Prepare a client’s VAT return",
        "tags": [
          "Practice VAT"
        ],
        "x-required-role": "preparer",
        "x-required-scopes": [
          "self_assessment:write"
        ],
        "x-required-product": "self_assessment"
      }
    },
    "/api/v1/practice-vat/returns/read-sheet": {
      "post": {
        "description": "Says what the rows give, and what’s wrong. Keeps nothing.\n\nNeeds the Preparer role or above. Scopes: `self_assessment:write`. Part of the `self_assessment` product: the firm must have it and you must have access to it.",
        "operationId": "PracticeVat_readSheet",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SpreadsheetRows"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PracticeVatSheetReading"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "self_assessment:write"
            ]
          }
        ],
        "summary": "Read a bridging sheet",
        "tags": [
          "Practice VAT"
        ],
        "x-required-role": "preparer",
        "x-required-scopes": [
          "self_assessment:write"
        ],
        "x-required-product": "self_assessment"
      }
    },
    "/api/v1/practice-vat/returns/{id}": {
      "get": {
        "operationId": "PracticeVat_get",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PracticeVatReturn"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "self_assessment:read"
            ]
          }
        ],
        "summary": "A client’s VAT return",
        "tags": [
          "Practice VAT"
        ],
        "x-required-scopes": [
          "self_assessment:read"
        ],
        "x-required-product": "self_assessment",
        "description": "Scopes: `self_assessment:read`. Part of the `self_assessment` product: the firm must have it and you must have access to it."
      }
    },
    "/api/v1/practice-vat/returns/{id}/approve": {
      "post": {
        "description": "By the firm’s approver setting, against the hash reviewed. Never available to API keys or connected assistants.\n\nNeeds the Manager role or above. Scopes: `self_assessment:write`. Part of the `self_assessment` product: the firm must have it and you must have access to it. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "PracticeVat_approve",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PracticeVatHash"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PracticeVatReturn"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Approve",
        "tags": [
          "Practice VAT"
        ],
        "x-required-role": "manager",
        "x-required-scopes": [
          "self_assessment:write"
        ],
        "x-required-product": "self_assessment",
        "x-session-only": true
      }
    },
    "/api/v1/practice-vat/returns/{id}/client-approval": {
      "post": {
        "description": "Never available to API keys or connected assistants.\n\nNeeds the Preparer role or above. Scopes: `self_assessment:write`. Part of the `self_assessment` product: the firm must have it and you must have access to it. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "PracticeVat_clientApproval",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PracticeVatClientApproval"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PracticeVatReturn"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Record the client’s approval",
        "tags": [
          "Practice VAT"
        ],
        "x-required-role": "preparer",
        "x-required-scopes": [
          "self_assessment:write"
        ],
        "x-required-product": "self_assessment",
        "x-session-only": true
      }
    },
    "/api/v1/practice-vat/returns/{id}/submit": {
      "post": {
        "description": "A manager or partner with a second factor, once approved and the client has approved. Answers 503 while off. Off by default. It has only run against a fake: HMRC has not reviewed or accepted any of it. Never available to API keys or connected assistants.\n\nNeeds the Manager role or above. Scopes: `self_assessment:write`. Part of the `self_assessment` product: the firm must have it and you must have access to it. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "PracticeVat_submit",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "A unique key (1-255 visible characters) to make retries safe. Replayed for 24 hours.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SubmitPracticeVat"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PracticeVatReturn"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "A request with this Idempotency-Key is still being processed.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "422": {
            "description": "This Idempotency-Key was already used for a different request.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "File with HMRC",
        "tags": [
          "Practice VAT"
        ],
        "x-required-role": "manager",
        "x-required-scopes": [
          "self_assessment:write"
        ],
        "x-required-product": "self_assessment",
        "x-session-only": true
      }
    },
    "/api/v1/mtd-income-tax/sources": {
      "get": {
        "operationId": "MtdIt_sources",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "clientId",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MtdItSourceList"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "self_assessment:read"
            ]
          }
        ],
        "summary": "List income sources",
        "tags": [
          "Making Tax Digital for Income Tax"
        ],
        "x-required-scopes": [
          "self_assessment:read"
        ],
        "x-required-product": "self_assessment",
        "description": "Scopes: `self_assessment:read`. Part of the `self_assessment` product: the firm must have it and you must have access to it."
      },
      "post": {
        "description": "A sole trade or UK property business. Never available to API keys or connected assistants.\n\nNeeds the Preparer role or above. Scopes: `self_assessment:write`. Part of the `self_assessment` product: the firm must have it and you must have access to it. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "MtdIt_addSource",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AddMtdItSource"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MtdItSource"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Add an income source",
        "tags": [
          "Making Tax Digital for Income Tax"
        ],
        "x-required-role": "preparer",
        "x-required-scopes": [
          "self_assessment:write"
        ],
        "x-required-product": "self_assessment",
        "x-session-only": true
      }
    },
    "/api/v1/mtd-income-tax/sources/{id}/obligations": {
      "get": {
        "description": "Worked out from the dates, and what’s been accepted here. Not read from HMRC.\n\nScopes: `self_assessment:read`. Part of the `self_assessment` product: the firm must have it and you must have access to it.",
        "operationId": "MtdIt_obligations",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "taxYearEnd",
            "required": true,
            "in": "query",
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MtdItObligations"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "self_assessment:read"
            ]
          }
        ],
        "summary": "The year’s four updates",
        "tags": [
          "Making Tax Digital for Income Tax"
        ],
        "x-required-scopes": [
          "self_assessment:read"
        ],
        "x-required-product": "self_assessment"
      }
    },
    "/api/v1/mtd-income-tax/sources/{id}/read-sheet": {
      "post": {
        "description": "Two columns: HMRC’s field name, and the amount from 6 April. Keeps nothing.\n\nNeeds the Preparer role or above. Scopes: `self_assessment:write`. Part of the `self_assessment` product: the firm must have it and you must have access to it.",
        "operationId": "MtdIt_readSheet",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "kind",
            "required": true,
            "in": "query",
            "schema": {
              "enum": [
                "self_employment",
                "uk_property"
              ],
              "type": "string"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SpreadsheetRows"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MtdItSheetReading"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "self_assessment:write"
            ]
          }
        ],
        "summary": "Read a spreadsheet",
        "tags": [
          "Making Tax Digital for Income Tax"
        ],
        "x-required-role": "preparer",
        "x-required-scopes": [
          "self_assessment:write"
        ],
        "x-required-product": "self_assessment"
      }
    },
    "/api/v1/mtd-income-tax/sources/{id}/updates": {
      "put": {
        "description": "Figures from 6 April to the date. Nothing is sent.\n\nNeeds the Preparer role or above. Scopes: `self_assessment:write`. Part of the `self_assessment` product: the firm must have it and you must have access to it.",
        "operationId": "MtdIt_saveUpdate",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SaveMtdItUpdate"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MtdItUpdate"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "self_assessment:write"
            ]
          }
        ],
        "summary": "Save a cumulative update",
        "tags": [
          "Making Tax Digital for Income Tax"
        ],
        "x-required-role": "preparer",
        "x-required-scopes": [
          "self_assessment:write"
        ],
        "x-required-product": "self_assessment"
      }
    },
    "/api/v1/mtd-income-tax/updates/{id}/approve": {
      "post": {
        "description": "Never available to API keys or connected assistants.\n\nNeeds the Reviewer role or above. Scopes: `self_assessment:write`. Part of the `self_assessment` product: the firm must have it and you must have access to it. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "MtdIt_approve",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MtdItHash"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MtdItUpdate"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Approve an update",
        "tags": [
          "Making Tax Digital for Income Tax"
        ],
        "x-required-role": "reviewer",
        "x-required-scopes": [
          "self_assessment:write"
        ],
        "x-required-product": "self_assessment",
        "x-session-only": true
      }
    },
    "/api/v1/mtd-income-tax/updates/{id}/submit": {
      "post": {
        "description": "Off by default. It has only run against a fake: HMRC has not reviewed or accepted any of it. Never available to API keys or connected assistants.\n\nNeeds the Manager role or above. Scopes: `self_assessment:write`. Part of the `self_assessment` product: the firm must have it and you must have access to it. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "MtdIt_submit",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "A unique key (1-255 visible characters) to make retries safe. Replayed for 24 hours.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SubmitMtdItUpdate"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MtdItUpdate"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "A request with this Idempotency-Key is still being processed.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "422": {
            "description": "This Idempotency-Key was already used for a different request.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Send an update",
        "tags": [
          "Making Tax Digital for Income Tax"
        ],
        "x-required-role": "manager",
        "x-required-scopes": [
          "self_assessment:write"
        ],
        "x-required-product": "self_assessment",
        "x-session-only": true
      }
    },
    "/api/v1/mtd-income-tax/declarations": {
      "get": {
        "operationId": "MtdIt_declaration",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "taxYearEnd",
            "required": true,
            "in": "query",
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "clientId",
            "required": true,
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MtdItDeclaration"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "self_assessment:read"
            ]
          }
        ],
        "summary": "Where a final declaration has got to",
        "tags": [
          "Making Tax Digital for Income Tax"
        ],
        "x-required-scopes": [
          "self_assessment:read"
        ],
        "x-required-product": "self_assessment",
        "description": "Scopes: `self_assessment:read`. Part of the `self_assessment` product: the firm must have it and you must have access to it."
      }
    },
    "/api/v1/mtd-income-tax/declarations/calculate": {
      "post": {
        "description": "HMRC’s intent to finalise. Errors stop the declaration. Off by default. It has only run against a fake: HMRC has not reviewed or accepted any of it. Never available to API keys or connected assistants.\n\nNeeds the Manager role or above. Scopes: `self_assessment:write`. Part of the `self_assessment` product: the firm must have it and you must have access to it. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "MtdIt_calculate",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MtdItDeclarationStep"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MtdItDeclaration"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Ask for the calculation",
        "tags": [
          "Making Tax Digital for Income Tax"
        ],
        "x-required-role": "manager",
        "x-required-scopes": [
          "self_assessment:write"
        ],
        "x-required-product": "self_assessment",
        "x-session-only": true
      }
    },
    "/api/v1/mtd-income-tax/declarations/review": {
      "post": {
        "description": "Never available to API keys or connected assistants.\n\nNeeds the Manager role or above. Scopes: `self_assessment:write`. Part of the `self_assessment` product: the firm must have it and you must have access to it. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "MtdIt_review",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MtdItDeclarationStep"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MtdItDeclaration"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Mark the calculation reviewed",
        "tags": [
          "Making Tax Digital for Income Tax"
        ],
        "x-required-role": "manager",
        "x-required-scopes": [
          "self_assessment:write"
        ],
        "x-required-product": "self_assessment",
        "x-session-only": true
      }
    },
    "/api/v1/mtd-income-tax/declarations/client-approval": {
      "post": {
        "description": "Never available to API keys or connected assistants.\n\nNeeds the Preparer role or above. Scopes: `self_assessment:write`. Part of the `self_assessment` product: the firm must have it and you must have access to it. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "MtdIt_confirmClient",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MtdItDeclarationStep"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MtdItDeclaration"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Record the client’s approval",
        "tags": [
          "Making Tax Digital for Income Tax"
        ],
        "x-required-role": "preparer",
        "x-required-scopes": [
          "self_assessment:write"
        ],
        "x-required-product": "self_assessment",
        "x-session-only": true
      }
    },
    "/api/v1/mtd-income-tax/declarations/submit": {
      "post": {
        "description": "With the calculation the client agreed to, and the agent’s confirmation. Off by default. It has only run against a fake: HMRC has not reviewed or accepted any of it. Never available to API keys or connected assistants.\n\nNeeds the Manager role or above. Scopes: `self_assessment:write`. Part of the `self_assessment` product: the firm must have it and you must have access to it. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "MtdIt_declare",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "A unique key (1-255 visible characters) to make retries safe. Replayed for 24 hours.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MtdItDeclarationStep"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MtdItDeclaration"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "A request with this Idempotency-Key is still being processed.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "422": {
            "description": "This Idempotency-Key was already used for a different request.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Submit the final declaration",
        "tags": [
          "Making Tax Digital for Income Tax"
        ],
        "x-required-role": "manager",
        "x-required-scopes": [
          "self_assessment:write"
        ],
        "x-required-product": "self_assessment",
        "x-session-only": true
      }
    },
    "/api/v1/self-assessment/informal-estate": {
      "post": {
        "description": "The year-by-year breakdown HMRC asks for by letter, and HMRC’s three tests for whether the informal route fits. Gains and Capital Gains Tax are as entered. Keeps nothing. Body: `deceasedName`, `dateOfDeath`, `administrationEnded`, `estateValuePence`, `years[]`.\n\nNeeds the Preparer role or above. Scopes: `self_assessment:write`. Part of the `self_assessment` product: the firm must have it and you must have access to it.",
        "operationId": "TrustTools_informalEstate",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": true
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "self_assessment:write"
            ]
          }
        ],
        "summary": "Work out an informal estate computation",
        "tags": [
          "Self Assessment"
        ],
        "x-required-role": "preparer",
        "x-required-scopes": [
          "self_assessment:write"
        ],
        "x-required-product": "self_assessment"
      }
    },
    "/api/v1/self-assessment/informal-estate/pdf": {
      "post": {
        "description": "As a PDF, for a person to check and send with their letter. Same body.\n\nNeeds the Preparer role or above. Scopes: `self_assessment:write`. Part of the `self_assessment` product: the firm must have it and you must have access to it.",
        "operationId": "TrustTools_informalEstatePdf",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": true
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "A PDF.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "self_assessment:write"
            ]
          }
        ],
        "summary": "Download an informal estate computation",
        "tags": [
          "Self Assessment"
        ],
        "x-required-role": "preparer",
        "x-required-scopes": [
          "self_assessment:write"
        ],
        "x-required-product": "self_assessment"
      }
    },
    "/api/v1/self-assessment/trust-accounts": {
      "post": {
        "description": "Capital and income apart, a distribution statement and whether the assets agree. No statutory format was found for a non-charitable trust: this is a working layout. Keeps nothing.\n\nNeeds the Preparer role or above. Scopes: `self_assessment:write`. Part of the `self_assessment` product: the firm must have it and you must have access to it.",
        "operationId": "TrustTools_trustAccounts",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": true
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "self_assessment:write"
            ]
          }
        ],
        "summary": "Work out a trust accounts pack",
        "tags": [
          "Self Assessment"
        ],
        "x-required-role": "preparer",
        "x-required-scopes": [
          "self_assessment:write"
        ],
        "x-required-product": "self_assessment"
      }
    },
    "/api/v1/self-assessment/trust-accounts/pdf": {
      "post": {
        "description": "As a PDF. Same body.\n\nNeeds the Preparer role or above. Scopes: `self_assessment:write`. Part of the `self_assessment` product: the firm must have it and you must have access to it.",
        "operationId": "TrustTools_trustAccountsPdf",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": true
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "A PDF.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "self_assessment:write"
            ]
          }
        ],
        "summary": "Download a trust accounts pack",
        "tags": [
          "Self Assessment"
        ],
        "x-required-role": "preparer",
        "x-required-scopes": [
          "self_assessment:write"
        ],
        "x-required-product": "self_assessment"
      }
    },
    "/api/v1/self-assessment/r40": {
      "post": {
        "description": "The figures for a repayment claim, and whether the R40 can be used. HMRC publishes no schema for it that could be found, so it can’t be sent from Tolvi and the repayment isn’t worked out. Keeps nothing.\n\nNeeds the Preparer role or above. Scopes: `self_assessment:write`. Part of the `self_assessment` product: the firm must have it and you must have access to it.",
        "operationId": "TrustTools_r40",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": true
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "self_assessment:write"
            ]
          }
        ],
        "summary": "Work out an R40 schedule",
        "tags": [
          "Self Assessment"
        ],
        "x-required-role": "preparer",
        "x-required-scopes": [
          "self_assessment:write"
        ],
        "x-required-product": "self_assessment"
      }
    },
    "/api/v1/self-assessment/r40/pdf": {
      "post": {
        "description": "A schedule to key from or post with evidence. It isn’t HMRC’s form. Same body.\n\nNeeds the Preparer role or above. Scopes: `self_assessment:write`. Part of the `self_assessment` product: the firm must have it and you must have access to it.",
        "operationId": "TrustTools_r40Pdf",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": true
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "A PDF.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "self_assessment:write"
            ]
          }
        ],
        "summary": "Download an R40 schedule",
        "tags": [
          "Self Assessment"
        ],
        "x-required-role": "preparer",
        "x-required-scopes": [
          "self_assessment:write"
        ],
        "x-required-product": "self_assessment"
      }
    },
    "/api/v1/self-assessment/trust-registrations/{clientId}": {
      "get": {
        "description": "What the practice has recorded. HMRC’s Trust Registration Service has no API that could be found, so this doesn’t come from HMRC.\n\nNeeds the Preparer role or above. Scopes: `self_assessment:read`. Part of the `self_assessment` product: the firm must have it and you must have access to it.",
        "operationId": "TrustTools_getRegistration",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "clientId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrustRegistration"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "self_assessment:read"
            ]
          }
        ],
        "summary": "A trust’s registration and what’s due",
        "tags": [
          "Self Assessment"
        ],
        "x-required-role": "preparer",
        "x-required-scopes": [
          "self_assessment:read"
        ],
        "x-required-product": "self_assessment"
      },
      "put": {
        "description": "The reference, whether it’s taxable, years of liability and what’s been confirmed. Reminders follow when they’re on.\n\nNeeds the Preparer role or above. Scopes: `self_assessment:write`. Part of the `self_assessment` product: the firm must have it and you must have access to it.",
        "operationId": "TrustTools_saveRegistration",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "clientId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": true
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrustRegistration"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "self_assessment:write"
            ]
          }
        ],
        "summary": "Record a trust’s registration",
        "tags": [
          "Self Assessment"
        ],
        "x-required-role": "preparer",
        "x-required-scopes": [
          "self_assessment:write"
        ],
        "x-required-product": "self_assessment"
      }
    },
    "/api/v1/work": {
      "get": {
        "description": "Saved views are relative to the caller (\"mine\" = engagements where you act next). Needs a person, not an API client.\n\nScopes: `work:read`. Part of the `working_papers` product: the firm must have it and you must have access to it.",
        "operationId": "Work_list",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 50
            }
          },
          {
            "name": "cursor",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "q",
            "required": false,
            "in": "query",
            "description": "Part of the client name.",
            "schema": {
              "type": "string",
              "maxLength": 100
            }
          },
          {
            "name": "partner",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "manager",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "actor",
            "required": false,
            "in": "query",
            "description": "Whose turn it is: the person assigned to the current stage.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "entityType",
            "required": false,
            "in": "query",
            "schema": {
              "$ref": "#/components/schemas/EntityType"
            }
          },
          {
            "name": "yearEndMonth",
            "required": false,
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 12
            }
          },
          {
            "name": "stage",
            "required": false,
            "in": "query",
            "schema": {
              "$ref": "#/components/schemas/EngagementStatus"
            }
          },
          {
            "name": "software",
            "required": false,
            "in": "query",
            "schema": {
              "$ref": "#/components/schemas/Software"
            }
          },
          {
            "name": "dueFrom",
            "required": false,
            "in": "query",
            "description": "Deadline on or after this date.",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "dueTo",
            "required": false,
            "in": "query",
            "description": "Deadline on or before this date.",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "scope",
            "required": false,
            "in": "query",
            "description": "mine: engagements where you are preparer, reviewer, manager or partner. Default everyone.",
            "schema": {
              "$ref": "#/components/schemas/WorkScope"
            }
          },
          {
            "name": "sort",
            "required": false,
            "in": "query",
            "description": "Default: due.",
            "schema": {
              "$ref": "#/components/schemas/WorkSort"
            }
          },
          {
            "name": "view",
            "required": false,
            "in": "query",
            "description": "Default: mine. todo/later: your turn, due within 120 days / after; stuck: in review over 14 days; at_risk: not yet overdue but likely to miss the deadline at its current stage (Due within 45 days and not started, 30 days preparing, 21 days returned or 14 days in review.); unassigned: open, no preparer (use scope=everyone); changed: open work only.",
            "schema": {
              "$ref": "#/components/schemas/WorkView"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WorkPage"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "work:read"
            ]
          }
        ],
        "summary": "List the work queue",
        "tags": [
          "Work"
        ],
        "x-required-scopes": [
          "work:read"
        ],
        "x-required-product": "working_papers"
      }
    },
    "/api/v1/work/counts": {
      "get": {
        "operationId": "Work_counts",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "q",
            "required": false,
            "in": "query",
            "description": "Part of the client name.",
            "schema": {
              "type": "string",
              "maxLength": 100
            }
          },
          {
            "name": "partner",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "manager",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "actor",
            "required": false,
            "in": "query",
            "description": "Whose turn it is: the person assigned to the current stage.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "entityType",
            "required": false,
            "in": "query",
            "schema": {
              "$ref": "#/components/schemas/EntityType"
            }
          },
          {
            "name": "yearEndMonth",
            "required": false,
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 12
            }
          },
          {
            "name": "stage",
            "required": false,
            "in": "query",
            "schema": {
              "$ref": "#/components/schemas/EngagementStatus"
            }
          },
          {
            "name": "software",
            "required": false,
            "in": "query",
            "schema": {
              "$ref": "#/components/schemas/Software"
            }
          },
          {
            "name": "dueFrom",
            "required": false,
            "in": "query",
            "description": "Deadline on or after this date.",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "dueTo",
            "required": false,
            "in": "query",
            "description": "Deadline on or before this date.",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "scope",
            "required": false,
            "in": "query",
            "description": "mine: engagements where you are preparer, reviewer, manager or partner. Default everyone.",
            "schema": {
              "$ref": "#/components/schemas/WorkScope"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WorkCounts"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "work:read"
            ]
          }
        ],
        "summary": "Count each saved view, with the KPI cards",
        "tags": [
          "Work"
        ],
        "x-required-scopes": [
          "work:read"
        ],
        "x-required-product": "working_papers",
        "description": "Scopes: `work:read`. Part of the `working_papers` product: the firm must have it and you must have access to it."
      }
    },
    "/api/v1/work/groups": {
      "get": {
        "description": "For the Board, Calendar and Workload. Same view, scope and filters as the list.\n\nScopes: `work:read`. Part of the `working_papers` product: the firm must have it and you must have access to it.",
        "operationId": "Work_groups",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "q",
            "required": false,
            "in": "query",
            "description": "Part of the client name.",
            "schema": {
              "type": "string",
              "maxLength": 100
            }
          },
          {
            "name": "partner",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "manager",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "actor",
            "required": false,
            "in": "query",
            "description": "Whose turn it is: the person assigned to the current stage.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "entityType",
            "required": false,
            "in": "query",
            "schema": {
              "$ref": "#/components/schemas/EntityType"
            }
          },
          {
            "name": "yearEndMonth",
            "required": false,
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 12
            }
          },
          {
            "name": "stage",
            "required": false,
            "in": "query",
            "schema": {
              "$ref": "#/components/schemas/EngagementStatus"
            }
          },
          {
            "name": "software",
            "required": false,
            "in": "query",
            "schema": {
              "$ref": "#/components/schemas/Software"
            }
          },
          {
            "name": "dueFrom",
            "required": false,
            "in": "query",
            "description": "Deadline on or after this date.",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "dueTo",
            "required": false,
            "in": "query",
            "description": "Deadline on or before this date.",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "scope",
            "required": false,
            "in": "query",
            "description": "mine: engagements where you are preparer, reviewer, manager or partner. Default everyone.",
            "schema": {
              "$ref": "#/components/schemas/WorkScope"
            }
          },
          {
            "name": "view",
            "required": false,
            "in": "query",
            "schema": {
              "$ref": "#/components/schemas/WorkView"
            }
          },
          {
            "name": "groupBy",
            "required": true,
            "in": "query",
            "schema": {
              "$ref": "#/components/schemas/WorkGroupBy"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WorkGroups"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "work:read"
            ]
          }
        ],
        "summary": "Count a view grouped by status, deadline day or whose turn it is",
        "tags": [
          "Work"
        ],
        "x-required-scopes": [
          "work:read"
        ],
        "x-required-product": "working_papers"
      }
    },
    "/api/v1/work/start": {
      "post": {
        "description": "Each start is billable (engagement.started, source web/api/mcp, or bulk for several). AI tokens come from the plan’s monthly allowance, not from each start. 402 when billing blocks starting (trial over without billing, or an invoice unpaid for 14 days).\n\nNeeds the Preparer role or above. Scopes: `engagements:write`, `work:read`. Part of the `working_papers` product: the firm must have it and you must have access to it.",
        "operationId": "Work_start",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "A unique key (1-255 visible characters) to make retries safe. Replayed for 24 hours.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/StartEngagements"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StartResult"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "A request with this Idempotency-Key is still being processed.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "422": {
            "description": "This Idempotency-Key was already used for a different request.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "engagements:write",
              "work:read"
            ]
          }
        ],
        "summary": "Start engagements (one or in bulk)",
        "tags": [
          "Work"
        ],
        "x-required-role": "preparer",
        "x-required-scopes": [
          "engagements:write",
          "work:read"
        ],
        "x-required-product": "working_papers"
      }
    },
    "/api/v1/work/filed": {
      "post": {
        "operationId": "Work_filed",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MarkFiled"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MarkFiledResult"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "engagements:write",
              "work:read"
            ]
          }
        ],
        "summary": "Record the dates accounts were filed",
        "tags": [
          "Work"
        ],
        "x-required-scopes": [
          "engagements:write",
          "work:read"
        ],
        "x-required-product": "working_papers",
        "description": "Scopes: `engagements:write`, `work:read`. Part of the `working_papers` product: the firm must have it and you must have access to it."
      }
    },
    "/api/v1/work/people": {
      "get": {
        "operationId": "Work_people",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Person"
                  }
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "work:read"
            ]
          }
        ],
        "summary": "List the firm’s people, for filters and assignment",
        "tags": [
          "Work"
        ],
        "x-required-scopes": [
          "work:read"
        ],
        "x-required-product": "working_papers",
        "description": "Scopes: `work:read`. Part of the `working_papers` product: the firm must have it and you must have access to it."
      }
    },
    "/api/v1/work/assign": {
      "post": {
        "description": "All or nothing: if any engagement id is not found in this firm, nothing is changed and the response is a 404 problem listing those ids.\n\nNeeds the Manager role or above. Scopes: `engagements:write`, `work:read`. Part of the `working_papers` product: the firm must have it and you must have access to it.",
        "operationId": "Work_assign",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "A unique key (1-255 visible characters) to make retries safe. Replayed for 24 hours.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AssignRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AssignResult"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "A request with this Idempotency-Key is still being processed.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "422": {
            "description": "This Idempotency-Key was already used for a different request.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "engagements:write",
              "work:read"
            ]
          }
        ],
        "summary": "Assign engagements in bulk",
        "tags": [
          "Work"
        ],
        "x-required-role": "manager",
        "x-required-scopes": [
          "engagements:write",
          "work:read"
        ],
        "x-required-product": "working_papers"
      }
    },
    "/api/v1/work/{id}": {
      "get": {
        "operationId": "Work_detail",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Engagement id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WorkDetail"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "work:read"
            ]
          }
        ],
        "summary": "Get one engagement with its workflow timeline",
        "tags": [
          "Work"
        ],
        "x-required-scopes": [
          "work:read"
        ],
        "x-required-product": "working_papers",
        "description": "Scopes: `work:read`. Part of the `working_papers` product: the firm must have it and you must have access to it."
      }
    },
    "/api/v1/invitations": {
      "get": {
        "operationId": "Invitations_list",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Invitation"
                  }
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "settings:admin"
            ]
          }
        ],
        "summary": "List the firm’s invitations",
        "tags": [
          "Invitations"
        ],
        "x-required-role": "admin",
        "x-required-scopes": [
          "settings:admin"
        ],
        "description": "Firm admins only. Scopes: `settings:admin`."
      },
      "post": {
        "description": "Emails them a single-use link. Web sessions only; you can’t grant a higher role than your own (owners excepted).\n\nFirm admins only. Scopes: `settings:admin`. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "Invitations_create",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "A unique key (1-255 visible characters) to make retries safe. Replayed for 24 hours.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateInvitationRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Invitation"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "A request with this Idempotency-Key is still being processed.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "422": {
            "description": "This Idempotency-Key was already used for a different request.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Invite someone to the firm",
        "tags": [
          "Invitations"
        ],
        "x-required-role": "admin",
        "x-required-scopes": [
          "settings:admin"
        ],
        "x-session-only": true
      }
    },
    "/api/v1/invitations/{id}/revoke": {
      "post": {
        "operationId": "Invitations_revoke",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "A unique key (1-255 visible characters) to make retries safe. Replayed for 24 hours.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Invitation"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "A request with this Idempotency-Key is still being processed.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "422": {
            "description": "This Idempotency-Key was already used for a different request.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "settings:admin"
            ]
          }
        ],
        "summary": "Revoke a pending invitation",
        "tags": [
          "Invitations"
        ],
        "x-required-role": "admin",
        "x-required-scopes": [
          "settings:admin"
        ],
        "description": "Firm admins only. Scopes: `settings:admin`."
      }
    },
    "/api/v1/invitations/accept": {
      "post": {
        "description": "Needs a sign-in token, but no firm yet.",
        "operationId": "InvitationAccept_accept",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AcceptInvitationRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AcceptInvitationResult"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Accept an invitation",
        "tags": [
          "Invitations"
        ]
      }
    },
    "/api/v1/invitations/preview": {
      "post": {
        "description": "What the link in an invitation email says, before signing in: the firm, who sent it, the role, when it expires and whether it can still be used (pending, accepted, revoked or expired). The address it was sent to comes back mostly hidden. No sign-in needed: the invitation token goes in the body, never in the URL. 404 for a token Tolvi doesn’t recognise. Rate limited per IP.",
        "operationId": "InvitationPreview_preview",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AcceptInvitationRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InvitationPreview"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "summary": "Preview an invitation",
        "tags": [
          "Invitations"
        ]
      }
    },
    "/api/v1/invitations/{id}/accept-for-me": {
      "post": {
        "description": "For a signed-in person with no firm yet: accepts an invitation from GET /me/pending-invitations without the emailed token. The invitation must have been sent to your email address, and your sign-in provider must have verified it. Each invitation can be accepted once. Sign-in tokens from the Tolvi web app only.",
        "operationId": "InvitationAcceptForMe_acceptForMe",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AcceptInvitationResult"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Accept one of your own pending invitations",
        "tags": [
          "Invitations"
        ]
      }
    },
    "/api/v1/me/pending-invitations": {
      "get": {
        "description": "Pending, unexpired invitations sent to your verified email address, with the firm, role and who sent them. Empty when your sign-in provider has not verified your email. Sign-in tokens from the Tolvi web app only.",
        "operationId": "PendingInvitations_list",
        "parameters": [],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/PendingInvitation"
                  }
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List invitations waiting for you",
        "tags": [
          "Invitations"
        ]
      }
    },
    "/api/v1/signup": {
      "post": {
        "description": "Creates the firm and its sign-in organisation, and emails the founder a single-use link. Following it confirms the address, has them choose a password and makes them the firm’s owner. No token needed. 503 when this server has no identity-provider Management API.",
        "operationId": "Signup_create",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SignUpRequest"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SignUpResult"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Sign-up is closed: people join by invitation (TOLVI_SIGNUP_OPEN is off).",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "summary": "Sign a new firm up",
        "tags": [
          "Sign-up"
        ]
      }
    },
    "/api/v1/credentials": {
      "get": {
        "description": "Firm admins see every personal access token and API client in the firm; everyone else sees their own tokens.\n\nOnly from a signed-in Tolvi session, never with an API token.",
        "operationId": "Credentials_list",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/ApiCredential"
                  }
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List API credentials",
        "tags": [
          "Credentials"
        ],
        "x-session-only": true
      }
    },
    "/api/v1/credentials/personal": {
      "post": {
        "description": "For scripts and tools acting as you. Scopes are capped by your role, now and whenever it changes.\n\nOnly from a signed-in Tolvi session, never with an API token.",
        "operationId": "Credentials_createPersonal",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreatePersonalTokenRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreatedCredential"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Create a personal access token",
        "tags": [
          "Credentials"
        ],
        "x-session-only": true
      }
    },
    "/api/v1/credentials/clients": {
      "post": {
        "description": "For server-to-server integrations. Exchange the client id and secret at POST /api/v1/oauth/token.\n\nFirm admins only. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "Credentials_createClient",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateApiClientRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreatedCredential"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Create an API client (client credentials)",
        "tags": [
          "Credentials"
        ],
        "x-required-role": "admin",
        "x-session-only": true
      }
    },
    "/api/v1/credentials/{id}/revoke": {
      "post": {
        "description": "Owners revoke their own tokens; firm admins revoke anything in the firm. Takes effect at once.\n\nOnly from a signed-in Tolvi session, never with an API token.",
        "operationId": "Credentials_revoke",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiCredential"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Revoke a personal access token or API client",
        "tags": [
          "Credentials"
        ],
        "x-session-only": true
      }
    },
    "/api/v1/audit-log": {
      "get": {
        "operationId": "Audit_list",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "cursor",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "via",
            "required": false,
            "in": "query",
            "schema": {
              "$ref": "#/components/schemas/AuditVia"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AuditPage"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "settings:admin"
            ]
          }
        ],
        "summary": "List the firm’s audit trail, newest first",
        "tags": [
          "Audit"
        ],
        "x-required-role": "admin",
        "x-required-scopes": [
          "settings:admin"
        ],
        "description": "Firm admins only. Scopes: `settings:admin`."
      }
    },
    "/api/v1/oauth/token": {
      "post": {
        "description": "Authenticate with HTTP Basic (client_id:client_secret) or client_id and client_secret in the body. The token acts as the API client: its scopes, capped by the client’s role.",
        "operationId": "Token_token",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/ClientCredentialsTokenRequest"
              }
            },
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ClientCredentialsTokenRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TokenResponse"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "invalid_request, unsupported_grant_type or invalid_scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OAuthError"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "401": {
            "description": "invalid_client.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OAuthError"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "summary": "Get an access token (client credentials)",
        "tags": [
          "OAuth"
        ]
      }
    },
    "/api/v1/engagements": {
      "post": {
        "description": "Creates the entity-aware section index and checklists (firm template, else built-in, plus the client’s own steps). Billable (engagement.started); AI tokens come from the plan’s monthly allowance, not from each start. 402 when billing blocks starting; 409 when the period overlaps one of the client’s existing engagements.\n\nNeeds the Preparer role or above. Scopes: `engagements:write`, `engagements:read`. Part of the `working_papers` product: the firm must have it and you must have access to it.",
        "operationId": "Engagements_create",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "A unique key (1-255 visible characters) to make retries safe. Replayed for 24 hours.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateEngagement"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EngagementOverview"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "A request with this Idempotency-Key is still being processed.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "422": {
            "description": "This Idempotency-Key was already used for a different request.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "engagements:write",
              "engagements:read"
            ]
          }
        ],
        "summary": "Start an engagement for a client",
        "tags": [
          "Engagements"
        ],
        "x-required-role": "preparer",
        "x-required-scopes": [
          "engagements:write",
          "engagements:read"
        ],
        "x-required-product": "working_papers"
      }
    },
    "/api/v1/engagements/{id}/cancel": {
      "post": {
        "description": "Only while nothing is signed off. Within 14 days of starting it is credited (not billed). The file stays readable; it leaves the Work queue.\n\nNeeds the Manager role or above. Scopes: `engagements:write`, `engagements:read`. Part of the `working_papers` product: the firm must have it and you must have access to it.",
        "operationId": "Engagements_cancel",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Engagement id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CancelResult"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "engagements:write",
              "engagements:read"
            ]
          }
        ],
        "summary": "Cancel an engagement",
        "tags": [
          "Engagements"
        ],
        "x-required-role": "manager",
        "x-required-scopes": [
          "engagements:write",
          "engagements:read"
        ],
        "x-required-product": "working_papers"
      }
    },
    "/api/v1/engagements/{id}": {
      "get": {
        "description": "Sections and statuses, workflow (with the actions checked for you), trial balance and your next step.\n\nScopes: `engagements:read`. Part of the `working_papers` product: the firm must have it and you must have access to it.",
        "operationId": "Engagements_overview",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Engagement id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EngagementOverview"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "engagements:read"
            ]
          }
        ],
        "summary": "Get an engagement overview",
        "tags": [
          "Engagements"
        ],
        "x-required-scopes": [
          "engagements:read"
        ],
        "x-required-product": "working_papers"
      }
    },
    "/api/v1/engagements/{id}/sections": {
      "get": {
        "operationId": "Engagements_sections",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Engagement id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/SectionSummary"
                  }
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "engagements:read"
            ]
          }
        ],
        "summary": "List the engagement’s sections and their statuses",
        "tags": [
          "Engagements"
        ],
        "x-required-scopes": [
          "engagements:read"
        ],
        "x-required-product": "working_papers",
        "description": "Scopes: `engagements:read`. Part of the `working_papers` product: the firm must have it and you must have access to it."
      }
    },
    "/api/v1/engagements/{id}/sections/{code}": {
      "get": {
        "operationId": "Engagements_section",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Engagement id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "code",
            "required": true,
            "in": "path",
            "description": "Section code (W/P ref), e.g. C.",
            "schema": {
              "type": "string",
              "enum": [
                "A",
                "B",
                "C",
                "D",
                "E",
                "F",
                "G",
                "H",
                "I",
                "J",
                "K",
                "L",
                "M",
                "T",
                "X",
                "Z"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SectionDetail"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "engagements:read"
            ]
          }
        ],
        "summary": "Get a section: checklist, issues, sign-off, review points, evidence and next step",
        "tags": [
          "Engagements"
        ],
        "x-required-scopes": [
          "engagements:read"
        ],
        "x-required-product": "working_papers",
        "description": "Scopes: `engagements:read`. Part of the `working_papers` product: the firm must have it and you must have access to it."
      }
    },
    "/api/v1/engagements/{id}/sections/{code}/lead-schedule": {
      "get": {
        "description": "Accounts by line with prior year, draft, journals and final balances, movements, variance notes and tickmarks.\n\nScopes: `engagements:read`. Part of the `working_papers` product: the firm must have it and you must have access to it.",
        "operationId": "Engagements_lead",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Engagement id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "code",
            "required": true,
            "in": "path",
            "description": "Section code (W/P ref), e.g. C.",
            "schema": {
              "type": "string",
              "enum": [
                "A",
                "B",
                "C",
                "D",
                "E",
                "F",
                "G",
                "H",
                "I",
                "J",
                "K",
                "L",
                "M",
                "T",
                "X",
                "Z"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LeadSchedule"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "engagements:read"
            ]
          }
        ],
        "summary": "Get a lead schedule",
        "tags": [
          "Engagements"
        ],
        "x-required-scopes": [
          "engagements:read"
        ],
        "x-required-product": "working_papers"
      }
    },
    "/api/v1/engagements/{id}/sections/{code}/reconciliations": {
      "get": {
        "operationId": "Engagements_reconciliations",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Engagement id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "code",
            "required": true,
            "in": "path",
            "description": "Section code (W/P ref), e.g. C.",
            "schema": {
              "type": "string",
              "enum": [
                "A",
                "B",
                "C",
                "D",
                "E",
                "F",
                "G",
                "H",
                "I",
                "J",
                "K",
                "L",
                "M",
                "T",
                "X",
                "Z"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Reconciliation"
                  }
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "engagements:read"
            ]
          }
        ],
        "summary": "List a section’s reconciliations (F bank, H VAT, I payroll)",
        "tags": [
          "Engagements"
        ],
        "x-required-scopes": [
          "engagements:read"
        ],
        "x-required-product": "working_papers",
        "description": "Scopes: `engagements:read`. Part of the `working_papers` product: the firm must have it and you must have access to it."
      }
    },
    "/api/v1/engagements/{id}/next-steps": {
      "get": {
        "operationId": "Engagements_nextSteps",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Engagement id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NextSteps"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "engagements:read"
            ]
          }
        ],
        "summary": "Get your next step on the engagement and each section",
        "tags": [
          "Engagements"
        ],
        "x-required-scopes": [
          "engagements:read"
        ],
        "x-required-product": "working_papers",
        "description": "Scopes: `engagements:read`. Part of the `working_papers` product: the firm must have it and you must have access to it."
      }
    },
    "/api/v1/engagements/{id}/accounts/{code}/note": {
      "put": {
        "description": "Only the note’s author can change it.\n\nScopes: `engagements:write`, `engagements:read`. Part of the `working_papers` product: the firm must have it and you must have access to it.",
        "operationId": "Engagements_setNote",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Engagement id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "code",
            "required": true,
            "in": "path",
            "description": "Account code.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SetVarianceNote"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LeadSchedule"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "engagements:write",
              "engagements:read"
            ]
          }
        ],
        "summary": "Write or change a variance note",
        "tags": [
          "Engagements"
        ],
        "x-required-scopes": [
          "engagements:write",
          "engagements:read"
        ],
        "x-required-product": "working_papers"
      },
      "delete": {
        "operationId": "Engagements_deleteNote",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Engagement id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "code",
            "required": true,
            "in": "path",
            "description": "Account code.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LeadSchedule"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "engagements:write",
              "engagements:read"
            ]
          }
        ],
        "summary": "Remove your variance note",
        "tags": [
          "Engagements"
        ],
        "x-required-scopes": [
          "engagements:write",
          "engagements:read"
        ],
        "x-required-product": "working_papers",
        "description": "Scopes: `engagements:write`, `engagements:read`. Part of the `working_papers` product: the firm must have it and you must have access to it."
      }
    },
    "/api/v1/engagements/{id}/accounts/{code}/tickmark": {
      "put": {
        "description": "Only the tickmark’s author can change it.\n\nScopes: `engagements:write`, `engagements:read`. Part of the `working_papers` product: the firm must have it and you must have access to it.",
        "operationId": "Engagements_setTick",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Engagement id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "code",
            "required": true,
            "in": "path",
            "description": "Account code.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SetTickmark"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LeadSchedule"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "engagements:write",
              "engagements:read"
            ]
          }
        ],
        "summary": "Set a tickmark",
        "tags": [
          "Engagements"
        ],
        "x-required-scopes": [
          "engagements:write",
          "engagements:read"
        ],
        "x-required-product": "working_papers"
      },
      "delete": {
        "operationId": "Engagements_deleteTick",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Engagement id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "code",
            "required": true,
            "in": "path",
            "description": "Account code.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LeadSchedule"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "engagements:write",
              "engagements:read"
            ]
          }
        ],
        "summary": "Remove your tickmark",
        "tags": [
          "Engagements"
        ],
        "x-required-scopes": [
          "engagements:write",
          "engagements:read"
        ],
        "x-required-product": "working_papers",
        "description": "Scopes: `engagements:write`, `engagements:read`. Part of the `working_papers` product: the firm must have it and you must have access to it."
      }
    },
    "/api/v1/engagements/{id}/reconciliations/{code}": {
      "put": {
        "operationId": "Engagements_setRec",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Engagement id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "code",
            "required": true,
            "in": "path",
            "description": "Account code of a bank, VAT or payroll control account.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SetReconciliation"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Reconciliation"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "engagements:write",
              "engagements:read"
            ]
          }
        ],
        "summary": "Set a reconciliation: source balance, reconciling items and note",
        "tags": [
          "Engagements"
        ],
        "x-required-scopes": [
          "engagements:write",
          "engagements:read"
        ],
        "x-required-product": "working_papers",
        "description": "Scopes: `engagements:write`, `engagements:read`. Part of the `working_papers` product: the firm must have it and you must have access to it."
      }
    },
    "/api/v1/engagements/{id}/checklist/{itemId}": {
      "patch": {
        "operationId": "Engagements_check",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Engagement id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "itemId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateChecklistItem"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SectionDetail"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "engagements:write",
              "engagements:read"
            ]
          }
        ],
        "summary": "Mark a checklist step done or N/A, or add a note",
        "tags": [
          "Engagements"
        ],
        "x-required-scopes": [
          "engagements:write",
          "engagements:read"
        ],
        "x-required-product": "working_papers",
        "description": "Scopes: `engagements:write`, `engagements:read`. Part of the `working_papers` product: the firm must have it and you must have access to it."
      }
    },
    "/api/v1/engagements/{id}/evidence": {
      "post": {
        "description": "Records the file and returns a short-lived presigned URL to PUT it to storage.\n\nScopes: `engagements:write`, `engagements:read`. Part of the `working_papers` product: the firm must have it and you must have access to it.",
        "operationId": "Engagements_createEvidence",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Engagement id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateEvidence"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EvidenceUpload"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "engagements:write",
              "engagements:read"
            ]
          }
        ],
        "summary": "Attach evidence",
        "tags": [
          "Engagements"
        ],
        "x-required-scopes": [
          "engagements:write",
          "engagements:read"
        ],
        "x-required-product": "working_papers"
      }
    },
    "/api/v1/engagements/{id}/evidence/{evidenceId}/confirm": {
      "post": {
        "description": "Call after the presigned PUT. Checks the stored file’s size, type and contents against what was declared, records its checksum (ETag) and starts the malware scan. Only confirmed, scanned files can be downloaded or read by Tolvi AI.\n\nScopes: `engagements:write`, `engagements:read`. Part of the `working_papers` product: the firm must have it and you must have access to it.",
        "operationId": "Engagements_confirmEvidence",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Engagement id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "evidenceId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Evidence"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "engagements:write",
              "engagements:read"
            ]
          }
        ],
        "summary": "Confirm an evidence upload",
        "tags": [
          "Engagements"
        ],
        "x-required-scopes": [
          "engagements:write",
          "engagements:read"
        ],
        "x-required-product": "working_papers"
      }
    },
    "/api/v1/engagements/{id}/evidence/{evidenceId}": {
      "get": {
        "description": "For following an upload through the malware scan: pending_upload, pending_scan, available, or rejected with the reason.\n\nScopes: `engagements:read`. Part of the `working_papers` product: the firm must have it and you must have access to it.",
        "operationId": "Engagements_getEvidence",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Engagement id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "evidenceId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Evidence"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "engagements:read"
            ]
          }
        ],
        "summary": "Get an evidence file’s status",
        "tags": [
          "Engagements"
        ],
        "x-required-scopes": [
          "engagements:read"
        ],
        "x-required-product": "working_papers"
      },
      "delete": {
        "operationId": "Engagements_deleteEvidence",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Engagement id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "evidenceId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "engagements:write",
              "engagements:read"
            ]
          }
        ],
        "summary": "Remove evidence you attached",
        "tags": [
          "Engagements"
        ],
        "x-required-scopes": [
          "engagements:write",
          "engagements:read"
        ],
        "x-required-product": "working_papers",
        "description": "Scopes: `engagements:write`, `engagements:read`. Part of the `working_papers` product: the firm must have it and you must have access to it."
      }
    },
    "/api/v1/engagements/{id}/evidence/{evidenceId}/upload": {
      "post": {
        "description": "A fresh presigned PUT for a file that is still pending_upload (the first PUT failed or its link expired), for the same size and type. Only the person who attached it; 409 once the file has been uploaded.\n\nScopes: `engagements:write`, `engagements:read`. Part of the `working_papers` product: the firm must have it and you must have access to it.",
        "operationId": "Engagements_presignEvidenceAgain",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Engagement id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "evidenceId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EvidenceUpload"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "engagements:write",
              "engagements:read"
            ]
          }
        ],
        "summary": "Presign an evidence upload again",
        "tags": [
          "Engagements"
        ],
        "x-required-scopes": [
          "engagements:write",
          "engagements:read"
        ],
        "x-required-product": "working_papers"
      }
    },
    "/api/v1/engagements/{id}/evidence/{evidenceId}/download": {
      "get": {
        "operationId": "Engagements_download",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Engagement id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "evidenceId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PresignedUpload"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "engagements:read"
            ]
          }
        ],
        "summary": "Get a short-lived download URL for evidence",
        "tags": [
          "Engagements"
        ],
        "x-required-scopes": [
          "engagements:read"
        ],
        "x-required-product": "working_papers",
        "description": "Scopes: `engagements:read`. Part of the `working_papers` product: the firm must have it and you must have access to it."
      }
    },
    "/api/v1/engagements/{id}/tb/preview": {
      "post": {
        "description": "Nothing is stored. Shows the header row and columns read (`layout`; send `columns` to choose them yourself), whether it balances, new and removed codes, the journals a re-import would remove and the sign-offs it would put out of date.\n\nScopes: `engagements:write`, `engagements:read`. Part of the `working_papers` product: the firm must have it and you must have access to it.",
        "operationId": "TrialBalance_preview",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Engagement id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TbImport"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TbImportPreview"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "engagements:write",
              "engagements:read"
            ]
          }
        ],
        "summary": "Preview a trial balance import",
        "tags": [
          "Trial balance"
        ],
        "x-required-scopes": [
          "engagements:write",
          "engagements:read"
        ],
        "x-required-product": "working_papers"
      }
    },
    "/api/v1/engagements/{id}/tb/versions": {
      "post": {
        "description": "Adds an immutable version in pence. If journals would be removed, send confirmJournalRemoval: true after showing the preview (409 otherwise). A file signed off at every stage takes a new trial balance only with reopenFile: true, which reopens it for re-approval in the same transaction: 409 without it, 403 for anyone who cannot reopen a file (a reviewer or above does). The preview’s importLock and GET …/mappings say so first.\n\nScopes: `engagements:write`, `engagements:read`. Part of the `working_papers` product: the firm must have it and you must have access to it.",
        "operationId": "TrialBalance_import",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Engagement id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "A unique key (1-255 visible characters) to make retries safe. Replayed for 24 hours.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TbImport"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TbImportResult"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "A request with this Idempotency-Key is still being processed.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "422": {
            "description": "This Idempotency-Key was already used for a different request.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "engagements:write",
              "engagements:read"
            ]
          }
        ],
        "summary": "Import a trial balance (CSV or JSON)",
        "tags": [
          "Trial balance"
        ],
        "x-required-scopes": [
          "engagements:write",
          "engagements:read"
        ],
        "x-required-product": "working_papers"
      },
      "get": {
        "operationId": "TrialBalance_versions",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Engagement id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/TbVersion"
                  }
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "engagements:read"
            ]
          }
        ],
        "summary": "List trial balance versions, newest first",
        "tags": [
          "Trial balance"
        ],
        "x-required-scopes": [
          "engagements:read"
        ],
        "x-required-product": "working_papers",
        "description": "Scopes: `engagements:read`. Part of the `working_papers` product: the firm must have it and you must have access to it."
      }
    },
    "/api/v1/engagements/{id}/tb": {
      "get": {
        "description": "Current version + posted journals, derived on every request and never stored.\n\nScopes: `engagements:read`. Part of the `working_papers` product: the firm must have it and you must have access to it.",
        "operationId": "TrialBalance_finalTb",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Engagement id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FinalTrialBalance"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "engagements:read"
            ]
          }
        ],
        "summary": "Get the final trial balance",
        "tags": [
          "Trial balance"
        ],
        "x-required-scopes": [
          "engagements:read"
        ],
        "x-required-product": "working_papers"
      }
    },
    "/api/v1/engagements/{id}/mappings": {
      "get": {
        "description": "Each account’s lead schedule line and why (client memory, firm rule or built-in).\n\nScopes: `engagements:read`. Part of the `working_papers` product: the firm must have it and you must have access to it.",
        "operationId": "TrialBalance_mappings",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Engagement id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Mappings"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "engagements:read"
            ]
          }
        ],
        "summary": "Get account mappings",
        "tags": [
          "Trial balance"
        ],
        "x-required-scopes": [
          "engagements:read"
        ],
        "x-required-product": "working_papers"
      },
      "put": {
        "description": "Remembered for the client’s future engagements unless remember is false. Once B’s review sign-off is current, only a reviewer or above can change mappings (403 with the reason, as for T and C); `lockedReason` on GET says so first.\n\nScopes: `engagements:write`, `engagements:read`. Part of the `working_papers` product: the firm must have it and you must have access to it.",
        "operationId": "TrialBalance_setMappings",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Engagement id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SetMappings"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Mappings"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "engagements:write",
              "engagements:read"
            ]
          }
        ],
        "summary": "Set account mappings",
        "tags": [
          "Trial balance"
        ],
        "x-required-scopes": [
          "engagements:write",
          "engagements:read"
        ],
        "x-required-product": "working_papers"
      }
    },
    "/api/v1/engagements/{id}/journals": {
      "get": {
        "operationId": "Journals_list",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Engagement id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Journal"
                  }
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "engagements:read"
            ]
          }
        ],
        "summary": "List journals",
        "tags": [
          "Journals"
        ],
        "x-required-scopes": [
          "engagements:read"
        ],
        "x-required-product": "working_papers",
        "description": "Scopes: `engagements:read`. Part of the `working_papers` product: the firm must have it and you must have access to it."
      },
      "post": {
        "description": "Debits must equal credits. A draft raises an issue on every lead section it touches. Preparers, reviewers, managers and partners can all do this; the audit trail records who.\n\nScopes: `engagements:write`, `engagements:read`. Part of the `working_papers` product: the firm must have it and you must have access to it.",
        "operationId": "Journals_create",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Engagement id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "A unique key (1-255 visible characters) to make retries safe. Replayed for 24 hours.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateJournal"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Journal"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "A request with this Idempotency-Key is still being processed.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "422": {
            "description": "This Idempotency-Key was already used for a different request.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "engagements:write",
              "engagements:read"
            ]
          }
        ],
        "summary": "Create a journal (draft by default)",
        "tags": [
          "Journals"
        ],
        "x-required-scopes": [
          "engagements:write",
          "engagements:read"
        ],
        "x-required-product": "working_papers"
      }
    },
    "/api/v1/engagements/{id}/journals/impact": {
      "post": {
        "description": "Works out, without saving anything, which sections’ content would change and whose sign-offs would go out of date if a new journal were saved (give its lines) or a saved journal were posted, unposted or deleted (give journalId and action). Also the headline figures that would move. Read access is enough.\n\nScopes: `engagements:read`. Part of the `working_papers` product: the firm must have it and you must have access to it.",
        "operationId": "Journals_impact",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Engagement id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/JournalImpactRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JournalImpact"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "engagements:read"
            ]
          }
        ],
        "summary": "Preview what a journal change would do",
        "tags": [
          "Journals"
        ],
        "x-required-scopes": [
          "engagements:read"
        ],
        "x-required-product": "working_papers"
      }
    },
    "/api/v1/engagements/{id}/journals/{journalId}/post": {
      "post": {
        "description": "Records who posted it (postedBy). Preparers, reviewers, managers and partners can all do this; the audit trail records who.\n\nScopes: `engagements:write`, `engagements:read`. Part of the `working_papers` product: the firm must have it and you must have access to it.",
        "operationId": "Journals_post",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Engagement id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "journalId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Journal"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "engagements:write",
              "engagements:read"
            ]
          }
        ],
        "summary": "Post a draft journal",
        "tags": [
          "Journals"
        ],
        "x-required-scopes": [
          "engagements:write",
          "engagements:read"
        ],
        "x-required-product": "working_papers"
      }
    },
    "/api/v1/engagements/{id}/journals/{journalId}/unpost": {
      "post": {
        "description": "Preparers, reviewers, managers and partners can unpost; the audit trail records who. A posted journal touching a section with a current review sign-off can only be unposted by a reviewer or above (403 for a preparer).\n\nScopes: `engagements:write`, `engagements:read`. Part of the `working_papers` product: the firm must have it and you must have access to it.",
        "operationId": "Journals_unpost",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Engagement id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "journalId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Journal"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "engagements:write",
              "engagements:read"
            ]
          }
        ],
        "summary": "Unpost a journal",
        "tags": [
          "Journals"
        ],
        "x-required-scopes": [
          "engagements:write",
          "engagements:read"
        ],
        "x-required-product": "working_papers"
      }
    },
    "/api/v1/engagements/{id}/journals/{journalId}": {
      "delete": {
        "description": "Same people and lock rule as unposting: a posted journal touching a reviewed section can only be deleted by a reviewer or above.\n\nScopes: `engagements:write`, `engagements:read`. Part of the `working_papers` product: the firm must have it and you must have access to it.",
        "operationId": "Journals_delete",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Engagement id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "journalId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "engagements:write",
              "engagements:read"
            ]
          }
        ],
        "summary": "Delete a journal",
        "tags": [
          "Journals"
        ],
        "x-required-scopes": [
          "engagements:write",
          "engagements:read"
        ],
        "x-required-product": "working_papers"
      }
    },
    "/api/v1/engagements/{id}/journal-accounts": {
      "get": {
        "description": "Accounts Tolvi added for journals when the client’s bookkeeping has none (for example a corporation tax charge and creditor), and the standard ones it suggests. They are in no TB version; the final TB shows them from posted journals only.\n\nScopes: `engagements:read`. Part of the `working_papers` product: the firm must have it and you must have access to it.",
        "operationId": "JournalAccounts_list",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Engagement id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JournalAccounts"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "engagements:read"
            ]
          }
        ],
        "summary": "List journal-only accounts",
        "tags": [
          "Journals"
        ],
        "x-required-scopes": [
          "engagements:read"
        ],
        "x-required-product": "working_papers"
      },
      "post": {
        "description": "Each needs a code not already on the engagement and a lead schedule line. The TB version is not changed. Returns the list.\n\nScopes: `engagements:write`, `engagements:read`. Part of the `working_papers` product: the firm must have it and you must have access to it.",
        "operationId": "JournalAccounts_create",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Engagement id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "A unique key (1-255 visible characters) to make retries safe. Replayed for 24 hours.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateJournalAccounts"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JournalAccounts"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "A request with this Idempotency-Key is still being processed.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "422": {
            "description": "This Idempotency-Key was already used for a different request.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "engagements:write",
              "engagements:read"
            ]
          }
        ],
        "summary": "Add journal-only accounts",
        "tags": [
          "Journals"
        ],
        "x-required-scopes": [
          "engagements:write",
          "engagements:read"
        ],
        "x-required-product": "working_papers"
      }
    },
    "/api/v1/engagements/{id}/journal-accounts/{code}": {
      "delete": {
        "description": "Refused (409) while any journal posts to it, C uses it for disposal proceeds, or an asset class uses it.\n\nScopes: `engagements:write`, `engagements:read`. Part of the `working_papers` product: the firm must have it and you must have access to it.",
        "operationId": "JournalAccounts_delete",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Engagement id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "code",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "maxLength": 50
            }
          }
        ],
        "responses": {
          "204": {
            "description": "",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "engagements:write",
              "engagements:read"
            ]
          }
        ],
        "summary": "Remove a journal-only account",
        "tags": [
          "Journals"
        ],
        "x-required-scopes": [
          "engagements:write",
          "engagements:read"
        ],
        "x-required-product": "working_papers"
      }
    },
    "/api/v1/engagements/{id}/accounts": {
      "get": {
        "description": "Every account C’s pickers and journal lines can use: the trial balance’s accounts, Tolvi’s journal-only accounts, and the client’s chart of accounts (read from their bookkeeping software, or imported from a CSV), including accounts with no balance in this TB. Each has its lead schedule line. An account with no balance yet that a class or journal uses shows in the final TB under the client’s own code.\n\nScopes: `engagements:read`. Part of the `working_papers` product: the firm must have it and you must have access to it.",
        "operationId": "EngagementAccounts_list",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Engagement id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EngagementAccounts"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "engagements:read"
            ]
          }
        ],
        "summary": "List the accounts to choose from",
        "tags": [
          "Journals"
        ],
        "x-required-scopes": [
          "engagements:read"
        ],
        "x-required-product": "working_papers"
      }
    },
    "/api/v1/engagements/{id}/tax": {
      "get": {
        "description": "From the final TB via @tolvi/tax-engine, with deferred tax on fixed assets.\n\nScopes: `engagements:read`. Part of the `working_papers` product: the firm must have it and you must have access to it.",
        "operationId": "Tax_get",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Engagement id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TaxComputation"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "engagements:read"
            ]
          }
        ],
        "summary": "Get the corporation tax computation",
        "tags": [
          "Tax"
        ],
        "x-required-scopes": [
          "engagements:read"
        ],
        "x-required-product": "working_papers"
      }
    },
    "/api/v1/engagements/{id}/tax/inputs": {
      "put": {
        "description": "Capital allowances and pools brought forward come from the fixed asset register (C); the old fields are ignored.\n\nScopes: `engagements:write`, `engagements:read`. Part of the `working_papers` product: the firm must have it and you must have access to it.",
        "operationId": "Tax_setInputs",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Engagement id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SetTaxInputs"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TaxComputation"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "engagements:write",
              "engagements:read"
            ]
          }
        ],
        "summary": "Set tax inputs (associated companies, other adjustments)",
        "tags": [
          "Tax"
        ],
        "x-required-scopes": [
          "engagements:write",
          "engagements:read"
        ],
        "x-required-product": "working_papers"
      }
    },
    "/api/v1/engagements/{id}/tax/journals/preview": {
      "post": {
        "description": "The journal that posting would make (lines, date and narrative), the earlier one it would replace, and what would change: sections whose content moves, sign-offs that go out of date and the headline figures. Nothing is saved. Read access is enough.\n\nScopes: `engagements:read`. Part of the `working_papers` product: the firm must have it and you must have access to it.",
        "operationId": "Tax_previewJournal",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Engagement id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PreviewTaxJournal"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TaxJournalPreview"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "engagements:read"
            ]
          }
        ],
        "summary": "Preview the tax or deferred tax journal",
        "tags": [
          "Tax"
        ],
        "x-required-scopes": [
          "engagements:read"
        ],
        "x-required-product": "working_papers"
      }
    },
    "/api/v1/engagements/{id}/tax/journals": {
      "post": {
        "description": "Brings the TB into line with the computation. Preparers, reviewers, managers and partners can post it; the audit trail records who. Once T has a current review sign-off only a reviewer or above can (403 for a preparer).\n\nScopes: `engagements:write`, `engagements:read`. Part of the `working_papers` product: the firm must have it and you must have access to it.",
        "operationId": "Tax_postJournal",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Engagement id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PostTaxJournal"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TaxJournalResult"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "engagements:write",
              "engagements:read"
            ]
          }
        ],
        "summary": "Post the tax or deferred tax journal",
        "tags": [
          "Tax"
        ],
        "x-required-scopes": [
          "engagements:write",
          "engagements:read"
        ],
        "x-required-product": "working_papers"
      }
    },
    "/api/v1/engagements/{id}/fixed-assets": {
      "get": {
        "description": "Classes and assets, movements by class, the reconciliation to the final TB, capital allowances by chargeable period and NBV against tax WDV.\n\nScopes: `engagements:read`. Part of the `working_papers` product: the firm must have it and you must have access to it.",
        "operationId": "FixedAssets_get",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Engagement id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FixedAssetRegister"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "engagements:read"
            ]
          }
        ],
        "summary": "Get the fixed asset register",
        "tags": [
          "Fixed assets"
        ],
        "x-required-scopes": [
          "engagements:read"
        ],
        "x-required-product": "working_papers"
      }
    },
    "/api/v1/engagements/{id}/fixed-assets/settings": {
      "put": {
        "operationId": "FixedAssets_setSettings",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Engagement id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/FixedAssetSettings"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FixedAssetRegister"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "engagements:write",
              "engagements:read"
            ]
          }
        ],
        "summary": "Set the depreciation part-year policy and the tax pools brought forward",
        "tags": [
          "Fixed assets"
        ],
        "x-required-scopes": [
          "engagements:write",
          "engagements:read"
        ],
        "x-required-product": "working_papers",
        "description": "Scopes: `engagements:write`, `engagements:read`. Part of the `working_papers` product: the firm must have it and you must have access to it."
      }
    },
    "/api/v1/engagements/{id}/fixed-assets/classes": {
      "post": {
        "description": "With its depreciation policy, default tax treatment and the TB accounts it reconciles to.\n\nScopes: `engagements:write`, `engagements:read`. Part of the `working_papers` product: the firm must have it and you must have access to it.",
        "operationId": "FixedAssets_createClass",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Engagement id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "A unique key (1-255 visible characters) to make retries safe. Replayed for 24 hours.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateFixedAssetClass"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FixedAssetRegister"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "A request with this Idempotency-Key is still being processed.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "422": {
            "description": "This Idempotency-Key was already used for a different request.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "engagements:write",
              "engagements:read"
            ]
          }
        ],
        "summary": "Add an asset class",
        "tags": [
          "Fixed assets"
        ],
        "x-required-scopes": [
          "engagements:write",
          "engagements:read"
        ],
        "x-required-product": "working_papers"
      }
    },
    "/api/v1/engagements/{id}/fixed-assets/classes/{classId}": {
      "patch": {
        "operationId": "FixedAssets_updateClass",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Engagement id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "classId",
            "required": true,
            "in": "path",
            "description": "Asset class id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateFixedAssetClass"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FixedAssetRegister"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "engagements:write",
              "engagements:read"
            ]
          }
        ],
        "summary": "Change an asset class",
        "tags": [
          "Fixed assets"
        ],
        "x-required-scopes": [
          "engagements:write",
          "engagements:read"
        ],
        "x-required-product": "working_papers",
        "description": "Scopes: `engagements:write`, `engagements:read`. Part of the `working_papers` product: the firm must have it and you must have access to it."
      },
      "delete": {
        "description": "409 while it still has assets.\n\nScopes: `engagements:write`, `engagements:read`. Part of the `working_papers` product: the firm must have it and you must have access to it.",
        "operationId": "FixedAssets_deleteClass",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Engagement id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "classId",
            "required": true,
            "in": "path",
            "description": "Asset class id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FixedAssetRegister"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "engagements:write",
              "engagements:read"
            ]
          }
        ],
        "summary": "Delete an empty asset class",
        "tags": [
          "Fixed assets"
        ],
        "x-required-scopes": [
          "engagements:write",
          "engagements:read"
        ],
        "x-required-product": "working_papers"
      }
    },
    "/api/v1/engagements/{id}/fixed-assets/assets": {
      "post": {
        "description": "Acquired before the period: brought forward, with its accumulated depreciation b/f. Acquired in the period: an addition.\n\nScopes: `engagements:write`, `engagements:read`. Part of the `working_papers` product: the firm must have it and you must have access to it.",
        "operationId": "FixedAssets_createAsset",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Engagement id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "A unique key (1-255 visible characters) to make retries safe. Replayed for 24 hours.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateFixedAsset"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FixedAssetRegister"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "A request with this Idempotency-Key is still being processed.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "422": {
            "description": "This Idempotency-Key was already used for a different request.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "engagements:write",
              "engagements:read"
            ]
          }
        ],
        "summary": "Add an asset",
        "tags": [
          "Fixed assets"
        ],
        "x-required-scopes": [
          "engagements:write",
          "engagements:read"
        ],
        "x-required-product": "working_papers"
      }
    },
    "/api/v1/engagements/{id}/fixed-assets/assets/{assetId}": {
      "patch": {
        "operationId": "FixedAssets_updateAsset",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Engagement id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "assetId",
            "required": true,
            "in": "path",
            "description": "Asset id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateFixedAsset"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FixedAssetRegister"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "engagements:write",
              "engagements:read"
            ]
          }
        ],
        "summary": "Change an asset",
        "tags": [
          "Fixed assets"
        ],
        "x-required-scopes": [
          "engagements:write",
          "engagements:read"
        ],
        "x-required-product": "working_papers",
        "description": "Scopes: `engagements:write`, `engagements:read`. Part of the `working_papers` product: the firm must have it and you must have access to it."
      },
      "delete": {
        "operationId": "FixedAssets_deleteAsset",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Engagement id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "assetId",
            "required": true,
            "in": "path",
            "description": "Asset id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FixedAssetRegister"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "engagements:write",
              "engagements:read"
            ]
          }
        ],
        "summary": "Delete an asset from the register",
        "tags": [
          "Fixed assets"
        ],
        "x-required-scopes": [
          "engagements:write",
          "engagements:read"
        ],
        "x-required-product": "working_papers",
        "description": "Scopes: `engagements:write`, `engagements:read`. Part of the `working_papers` product: the firm must have it and you must have access to it."
      }
    },
    "/api/v1/engagements/{id}/fixed-assets/assets/preview": {
      "post": {
        "description": "A dry run of Add an asset, with the same checks: the asset’s depreciation charge, net book value, the allowance claimed and its pool, and the register’s totals before and after. Nothing is stored.\n\nScopes: `engagements:write`, `engagements:read`. Part of the `working_papers` product: the firm must have it and you must have access to it.",
        "operationId": "FixedAssets_previewCreate",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Engagement id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateFixedAsset"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FixedAssetPreview"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "engagements:write",
              "engagements:read"
            ]
          }
        ],
        "summary": "Preview adding an asset",
        "tags": [
          "Fixed assets"
        ],
        "x-required-scopes": [
          "engagements:write",
          "engagements:read"
        ],
        "x-required-product": "working_papers"
      }
    },
    "/api/v1/engagements/{id}/fixed-assets/assets/{assetId}/preview": {
      "post": {
        "description": "A dry run of Change an asset: what the register would show. Nothing is stored.\n\nScopes: `engagements:write`, `engagements:read`. Part of the `working_papers` product: the firm must have it and you must have access to it.",
        "operationId": "FixedAssets_previewUpdate",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Engagement id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "assetId",
            "required": true,
            "in": "path",
            "description": "Asset id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateFixedAsset"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FixedAssetPreview"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "engagements:write",
              "engagements:read"
            ]
          }
        ],
        "summary": "Preview changing an asset",
        "tags": [
          "Fixed assets"
        ],
        "x-required-scopes": [
          "engagements:write",
          "engagements:read"
        ],
        "x-required-product": "working_papers"
      }
    },
    "/api/v1/engagements/{id}/fixed-assets/assets/{assetId}/disposal/preview": {
      "post": {
        "description": "A dry run of Record the disposal: NBV at disposal, profit or loss on disposal, the disposal value deducted from the pool (capped at cost) and any balancing allowance or charge. Nothing is stored.\n\nScopes: `engagements:write`, `engagements:read`. Part of the `working_papers` product: the firm must have it and you must have access to it.",
        "operationId": "FixedAssets_previewDisposal",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Engagement id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "assetId",
            "required": true,
            "in": "path",
            "description": "Asset id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/FixedAssetDisposal"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FixedAssetPreview"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "engagements:write",
              "engagements:read"
            ]
          }
        ],
        "summary": "Preview a disposal",
        "tags": [
          "Fixed assets"
        ],
        "x-required-scopes": [
          "engagements:write",
          "engagements:read"
        ],
        "x-required-product": "working_papers"
      }
    },
    "/api/v1/engagements/{id}/fixed-assets/assets/{assetId}/disposal": {
      "put": {
        "description": "In the period. Proceeds may be null until known, but C cannot be signed off until every disposal has them (nil for an asset scrapped).\n\nScopes: `engagements:write`, `engagements:read`. Part of the `working_papers` product: the firm must have it and you must have access to it.",
        "operationId": "FixedAssets_setDisposal",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Engagement id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "assetId",
            "required": true,
            "in": "path",
            "description": "Asset id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/FixedAssetDisposal"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FixedAssetRegister"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "engagements:write",
              "engagements:read"
            ]
          }
        ],
        "summary": "Record the disposal of an asset",
        "tags": [
          "Fixed assets"
        ],
        "x-required-scopes": [
          "engagements:write",
          "engagements:read"
        ],
        "x-required-product": "working_papers"
      },
      "delete": {
        "operationId": "FixedAssets_clearDisposal",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Engagement id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "assetId",
            "required": true,
            "in": "path",
            "description": "Asset id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FixedAssetRegister"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "engagements:write",
              "engagements:read"
            ]
          }
        ],
        "summary": "Remove a disposal (the asset is held again)",
        "tags": [
          "Fixed assets"
        ],
        "x-required-scopes": [
          "engagements:write",
          "engagements:read"
        ],
        "x-required-product": "working_papers",
        "description": "Scopes: `engagements:write`, `engagements:read`. Part of the `working_papers` product: the firm must have it and you must have access to it."
      }
    },
    "/api/v1/engagements/{id}/fixed-assets/journal/preview": {
      "post": {
        "description": "The journal that posting would make (lines, date and narrative), the earlier fixed asset journal it would replace, differences it cannot put right, and what would change: sections whose content moves, sign-offs that go out of date and the headline figures. Nothing is saved. Read access is enough.\n\nScopes: `engagements:read`. Part of the `working_papers` product: the firm must have it and you must have access to it.",
        "operationId": "FixedAssets_previewJournal",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Engagement id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FixedAssetJournalPreview"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "engagements:read"
            ]
          }
        ],
        "summary": "Preview the fixed asset journal",
        "tags": [
          "Fixed assets"
        ],
        "x-required-scopes": [
          "engagements:read"
        ],
        "x-required-product": "working_papers"
      }
    },
    "/api/v1/engagements/{id}/fixed-assets/journal": {
      "post": {
        "description": "Brings each class’s TB accounts to the register: disposals derecognised to profit/loss on disposal and depreciation charged. 409 if one exists unless replace is true; 422 for differences it cannot put right (e.g. unposted additions).\n\nScopes: `engagements:write`, `engagements:read`. Part of the `working_papers` product: the firm must have it and you must have access to it.",
        "operationId": "FixedAssets_postJournal",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Engagement id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PostFixedAssetJournal"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FixedAssetJournalResult"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "engagements:write",
              "engagements:read"
            ]
          }
        ],
        "summary": "Post the fixed asset journal",
        "tags": [
          "Fixed assets"
        ],
        "x-required-scopes": [
          "engagements:write",
          "engagements:read"
        ],
        "x-required-product": "working_papers"
      }
    },
    "/api/v1/engagements/{id}/roll-forward": {
      "get": {
        "description": "The year-end roll forward: the source engagement, what was brought forward (final TB as comparatives, mappings, fixed asset register, pools and losses, variance notes as hints), whether the prior year changed since (content fingerprint) and whether it can be rolled again.\n\nScopes: `engagements:read`. Part of the `working_papers` product: the firm must have it and you must have access to it.",
        "operationId": "RollForward_get",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Engagement id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RollForward"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "engagements:read"
            ]
          }
        ],
        "summary": "Get what was brought forward from the prior year",
        "tags": [
          "Engagements"
        ],
        "x-required-scopes": [
          "engagements:read"
        ],
        "x-required-product": "working_papers"
      },
      "post": {
        "description": "Brings forward again from the client’s previous engagement, replacing what an earlier roll forward brought (this year’s additions and disposals are kept). Only while the file is Not started or Preparing (409 otherwise); 422 when there is no earlier engagement. Never copies sign-offs, review points or evidence; sign-offs on changed sections go stale.\n\nNeeds the Preparer role or above. Scopes: `engagements:write`, `engagements:read`. Part of the `working_papers` product: the firm must have it and you must have access to it.",
        "operationId": "RollForward_reroll",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Engagement id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "A unique key (1-255 visible characters) to make retries safe. Replayed for 24 hours.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            }
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RollForwardOptions"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RollForward"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "A request with this Idempotency-Key is still being processed.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "422": {
            "description": "This Idempotency-Key was already used for a different request.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "engagements:write",
              "engagements:read"
            ]
          }
        ],
        "summary": "Re-roll from prior year",
        "tags": [
          "Engagements"
        ],
        "x-required-role": "preparer",
        "x-required-scopes": [
          "engagements:write",
          "engagements:read"
        ],
        "x-required-product": "working_papers"
      }
    },
    "/api/v1/engagements/{id}/self-assessment": {
      "get": {
        "description": "Sole traders, partnerships and LLPs: adjusted profit, capital allowances, tax-year basis apportionment, transition profit, partner allocation, Class 4 NIC and the SA103 or SA800 figures. 404 for companies.\n\nScopes: `engagements:read`. Part of the `working_papers` product: the firm must have it and you must have access to it.",
        "operationId": "SelfAssessment_get",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Engagement id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SelfAssessmentComputation"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "engagements:read"
            ]
          }
        ],
        "summary": "Get the self assessment computation",
        "tags": [
          "Tax"
        ],
        "x-required-scopes": [
          "engagements:read"
        ],
        "x-required-product": "working_papers"
      }
    },
    "/api/v1/engagements/{id}/self-assessment/inputs": {
      "put": {
        "description": "Replaces the whole set: expense treatment, adjustments, other periods of account, transition and overlap figures, partners and the profit-sharing arrangement. Locked to reviewers once T is reviewed.\n\nScopes: `engagements:write`, `engagements:read`. Part of the `working_papers` product: the firm must have it and you must have access to it.",
        "operationId": "SelfAssessment_setInputs",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Engagement id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SetSelfAssessmentInputs"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SelfAssessmentComputation"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "engagements:write",
              "engagements:read"
            ]
          }
        ],
        "summary": "Set the self assessment inputs",
        "tags": [
          "Tax"
        ],
        "x-required-scopes": [
          "engagements:write",
          "engagements:read"
        ],
        "x-required-product": "working_papers"
      }
    },
    "/api/v1/engagements/{id}/review-points": {
      "get": {
        "operationId": "ReviewPoints_list",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Engagement id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "section",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "A",
                "B",
                "C",
                "D",
                "E",
                "F",
                "G",
                "H",
                "I",
                "J",
                "K",
                "L",
                "M",
                "T",
                "X",
                "Z"
              ]
            }
          },
          {
            "name": "status",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "open",
                "answered",
                "cleared",
                "reopened",
                "outstanding"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/ReviewPoint"
                  }
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "engagements:read"
            ]
          }
        ],
        "summary": "List review points",
        "tags": [
          "Review points"
        ],
        "x-required-scopes": [
          "engagements:read"
        ],
        "x-required-product": "working_papers",
        "description": "Scopes: `engagements:read`. Part of the `working_papers` product: the firm must have it and you must have access to it."
      },
      "post": {
        "description": "On reviewed work this withdraws the review sign-off. @mentions are notified.\n\nNeeds the Reviewer role or above. Scopes: `review:write`, `engagements:read`. Part of the `working_papers` product: the firm must have it and you must have access to it.",
        "operationId": "ReviewPoints_raise",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Engagement id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "A unique key (1-255 visible characters) to make retries safe. Replayed for 24 hours.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RaiseReviewPoint"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReviewPoint"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "A request with this Idempotency-Key is still being processed.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "422": {
            "description": "This Idempotency-Key was already used for a different request.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "review:write",
              "engagements:read"
            ]
          }
        ],
        "summary": "Raise a review point",
        "tags": [
          "Review points"
        ],
        "x-required-role": "reviewer",
        "x-required-scopes": [
          "review:write",
          "engagements:read"
        ],
        "x-required-product": "working_papers"
      }
    },
    "/api/v1/engagements/{id}/review-points/{pointId}": {
      "get": {
        "operationId": "ReviewPoints_get",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Engagement id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "pointId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReviewPoint"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "engagements:read"
            ]
          }
        ],
        "summary": "Get a review point with its thread",
        "tags": [
          "Review points"
        ],
        "x-required-scopes": [
          "engagements:read"
        ],
        "x-required-product": "working_papers",
        "description": "Scopes: `engagements:read`. Part of the `working_papers` product: the firm must have it and you must have access to it."
      }
    },
    "/api/v1/engagements/{id}/review-points/{pointId}/comments": {
      "post": {
        "description": "With @mentions and evidence uploaded for the point.\n\nScopes: `engagements:write`, `engagements:read`. Part of the `working_papers` product: the firm must have it and you must have access to it.",
        "operationId": "ReviewPoints_comment",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Engagement id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "pointId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "A unique key (1-255 visible characters) to make retries safe. Replayed for 24 hours.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ReviewPointReply"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReviewPoint"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "A request with this Idempotency-Key is still being processed.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "422": {
            "description": "This Idempotency-Key was already used for a different request.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "engagements:write",
              "engagements:read"
            ]
          }
        ],
        "summary": "Comment on a review point",
        "tags": [
          "Review points"
        ],
        "x-required-scopes": [
          "engagements:write",
          "engagements:read"
        ],
        "x-required-product": "working_papers"
      }
    },
    "/api/v1/engagements/{id}/review-points/{pointId}/answer": {
      "post": {
        "description": "Moves an open or reopened point to answered.\n\nScopes: `engagements:write`, `engagements:read`. Part of the `working_papers` product: the firm must have it and you must have access to it.",
        "operationId": "ReviewPoints_answer",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Engagement id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "pointId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ReviewPointReply"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReviewPoint"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "engagements:write",
              "engagements:read"
            ]
          }
        ],
        "summary": "Answer a review point",
        "tags": [
          "Review points"
        ],
        "x-required-scopes": [
          "engagements:write",
          "engagements:read"
        ],
        "x-required-product": "working_papers"
      }
    },
    "/api/v1/engagements/{id}/review-points/{pointId}/clear": {
      "post": {
        "description": "Only the stage that raised it, or a later one.\n\nNeeds the Reviewer role or above. Scopes: `review:write`, `engagements:read`. Part of the `working_papers` product: the firm must have it and you must have access to it.",
        "operationId": "ReviewPoints_clear",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Engagement id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "pointId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ReviewPointAction"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReviewPoint"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "review:write",
              "engagements:read"
            ]
          }
        ],
        "summary": "Clear a review point",
        "tags": [
          "Review points"
        ],
        "x-required-role": "reviewer",
        "x-required-scopes": [
          "review:write",
          "engagements:read"
        ],
        "x-required-product": "working_papers"
      }
    },
    "/api/v1/engagements/{id}/review-points/{pointId}/reopen": {
      "post": {
        "description": "An answered or cleared point, with a message saying why.\n\nNeeds the Reviewer role or above. Scopes: `review:write`, `engagements:read`. Part of the `working_papers` product: the firm must have it and you must have access to it.",
        "operationId": "ReviewPoints_reopen",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Engagement id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "pointId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ReviewPointAction"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReviewPoint"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "review:write",
              "engagements:read"
            ]
          }
        ],
        "summary": "Reopen a review point",
        "tags": [
          "Review points"
        ],
        "x-required-role": "reviewer",
        "x-required-scopes": [
          "review:write",
          "engagements:read"
        ],
        "x-required-product": "working_papers"
      }
    },
    "/api/v1/engagements/{id}/sections/{code}/sign": {
      "post": {
        "description": "Preparer sign-off, or a review stage’s (which also needs review:write). Records the content fingerprint. Not available through MCP.\n\nScopes: `engagements:write`, `engagements:read`. Part of the `working_papers` product: the firm must have it and you must have access to it.",
        "operationId": "Workflow_sign",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Engagement id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "code",
            "required": true,
            "in": "path",
            "description": "Section code (W/P ref), e.g. C.",
            "schema": {
              "type": "string",
              "enum": [
                "A",
                "B",
                "C",
                "D",
                "E",
                "F",
                "G",
                "H",
                "I",
                "J",
                "K",
                "L",
                "M",
                "T",
                "X",
                "Z"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SectionDetail"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "engagements:write",
              "engagements:read"
            ]
          }
        ],
        "summary": "Sign a section off at its current stage",
        "tags": [
          "Workflow"
        ],
        "x-required-scopes": [
          "engagements:write",
          "engagements:read"
        ],
        "x-required-product": "working_papers"
      }
    },
    "/api/v1/engagements/{id}/sections/{code}/unsign": {
      "post": {
        "description": "Later sign-offs are removed with it (the section detail’s signOff.unsignRemoves lists them). Refused (409) while the file is signed off at every stage: reopen it for re-approval first.\n\nScopes: `engagements:write`, `engagements:read`. Part of the `working_papers` product: the firm must have it and you must have access to it.",
        "operationId": "Workflow_unsign",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Engagement id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "code",
            "required": true,
            "in": "path",
            "description": "Section code (W/P ref), e.g. C.",
            "schema": {
              "type": "string",
              "enum": [
                "A",
                "B",
                "C",
                "D",
                "E",
                "F",
                "G",
                "H",
                "I",
                "J",
                "K",
                "L",
                "M",
                "T",
                "X",
                "Z"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SectionDetail"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "engagements:write",
              "engagements:read"
            ]
          }
        ],
        "summary": "Remove your own sign-off from a section",
        "tags": [
          "Workflow"
        ],
        "x-required-scopes": [
          "engagements:write",
          "engagements:read"
        ],
        "x-required-product": "working_papers"
      }
    },
    "/api/v1/engagements/{id}/workflow": {
      "get": {
        "operationId": "Workflow_history",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Engagement id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WorkflowHistory"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "engagements:read"
            ]
          }
        ],
        "summary": "Get the engagement workflow and its event history",
        "tags": [
          "Workflow"
        ],
        "x-required-scopes": [
          "engagements:read"
        ],
        "x-required-product": "working_papers",
        "description": "Scopes: `engagements:read`. Part of the `working_papers` product: the firm must have it and you must have access to it."
      }
    },
    "/api/v1/engagements/{id}/workflow/submit": {
      "post": {
        "description": "Every section prepared and unchanged, no unanswered review points. Optionally name who takes the next stage (reviewerId, saved on the team) and leave them a note. Not available through MCP.\n\nScopes: `engagements:write`, `engagements:read`. Part of the `working_papers` product: the firm must have it and you must have access to it.",
        "operationId": "Workflow_submit",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Engagement id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SubmitEngagement"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EngagementWorkflow"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "engagements:write",
              "engagements:read"
            ]
          }
        ],
        "summary": "Submit the engagement for review",
        "tags": [
          "Workflow"
        ],
        "x-required-scopes": [
          "engagements:write",
          "engagements:read"
        ],
        "x-required-product": "working_papers"
      }
    },
    "/api/v1/engagements/{id}/workflow/approve": {
      "post": {
        "description": "Segregation of duties and every workflow guard apply. Optionally name who takes the next stage (reviewerId, saved on the team as on submit, and told). An optional note and declaration (with the approver’s typed initials) are kept with the approval in the history and the audit trail. Not available through MCP.\n\nNeeds the Reviewer role or above. Scopes: `review:write`, `engagements:read`. Part of the `working_papers` product: the firm must have it and you must have access to it.",
        "operationId": "Workflow_approve",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Engagement id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ApproveEngagement"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EngagementWorkflow"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "review:write",
              "engagements:read"
            ]
          }
        ],
        "summary": "Approve the engagement at its current stage",
        "tags": [
          "Workflow"
        ],
        "x-required-role": "reviewer",
        "x-required-scopes": [
          "review:write",
          "engagements:read"
        ],
        "x-required-product": "working_papers"
      }
    },
    "/api/v1/engagements/{id}/workflow/return": {
      "post": {
        "description": "Needs at least one unanswered review point; starts a new amendment round. An optional note for the preparer is kept in the history and sent with the notification.\n\nNeeds the Reviewer role or above. Scopes: `review:write`, `engagements:read`. Part of the `working_papers` product: the firm must have it and you must have access to it.",
        "operationId": "Workflow_returnToStage",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Engagement id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ReturnEngagement"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EngagementWorkflow"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "review:write",
              "engagements:read"
            ]
          }
        ],
        "summary": "Return the engagement to an earlier stage",
        "tags": [
          "Workflow"
        ],
        "x-required-role": "reviewer",
        "x-required-scopes": [
          "review:write",
          "engagements:read"
        ],
        "x-required-product": "working_papers"
      }
    },
    "/api/v1/engagements/{id}/workflow/reopen": {
      "post": {
        "description": "Approvals from the target stage on go stale.\n\nNeeds the Reviewer role or above. Scopes: `review:write`, `engagements:read`. Part of the `working_papers` product: the firm must have it and you must have access to it.",
        "operationId": "Workflow_reopen",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Engagement id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ReopenEngagement"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EngagementWorkflow"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "review:write",
              "engagements:read"
            ]
          }
        ],
        "summary": "Reopen an approved engagement whose content changed",
        "tags": [
          "Workflow"
        ],
        "x-required-role": "reviewer",
        "x-required-scopes": [
          "review:write",
          "engagements:read"
        ],
        "x-required-product": "working_papers"
      }
    },
    "/api/v1/notifications": {
      "get": {
        "operationId": "Notifications_list",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "unread",
            "required": false,
            "in": "query",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 50
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NotificationPage"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "work:read"
            ]
          }
        ],
        "summary": "List your notifications, newest first",
        "tags": [
          "Notifications"
        ],
        "x-required-scopes": [
          "work:read"
        ],
        "description": "Scopes: `work:read`."
      }
    },
    "/api/v1/notifications/{notificationId}/read": {
      "post": {
        "operationId": "Notifications_read",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "notificationId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Notification"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "work:read"
            ]
          }
        ],
        "summary": "Mark a notification read",
        "tags": [
          "Notifications"
        ],
        "x-required-scopes": [
          "work:read"
        ],
        "description": "Scopes: `work:read`."
      }
    },
    "/api/v1/settings/mapping-rules": {
      "get": {
        "operationId": "WorkingPaperSettings_rules",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MappingRules"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "engagements:read"
            ]
          }
        ],
        "summary": "Get the firm’s mapping rules, in order",
        "tags": [
          "Settings"
        ],
        "x-required-scopes": [
          "engagements:read"
        ],
        "x-required-product": "working_papers",
        "description": "Scopes: `engagements:read`. Part of the `working_papers` product: the firm must have it and you must have access to it."
      },
      "put": {
        "description": "Applied after client memory and before the built-in matcher.\n\nFirm admins only. Scopes: `settings:admin`. Part of the `working_papers` product: the firm must have it and you must have access to it.",
        "operationId": "WorkingPaperSettings_setRules",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MappingRules"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MappingRules"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "settings:admin"
            ]
          }
        ],
        "summary": "Replace the firm’s mapping rules",
        "tags": [
          "Settings"
        ],
        "x-required-role": "admin",
        "x-required-scopes": [
          "settings:admin"
        ],
        "x-required-product": "working_papers"
      }
    },
    "/api/v1/settings/checklists": {
      "get": {
        "operationId": "WorkingPaperSettings_checklists",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/ChecklistTemplate"
                  }
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "engagements:read"
            ]
          }
        ],
        "summary": "Get the firm’s checklist template for every section",
        "tags": [
          "Settings"
        ],
        "x-required-scopes": [
          "engagements:read"
        ],
        "x-required-product": "working_papers",
        "description": "Scopes: `engagements:read`. Part of the `working_papers` product: the firm must have it and you must have access to it."
      }
    },
    "/api/v1/settings/checklists/{code}": {
      "put": {
        "description": "Used for engagements started from now on.\n\nFirm admins only. Scopes: `settings:admin`. Part of the `working_papers` product: the firm must have it and you must have access to it.",
        "operationId": "WorkingPaperSettings_setChecklist",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "code",
            "required": true,
            "in": "path",
            "description": "Section code (W/P ref), e.g. C.",
            "schema": {
              "type": "string",
              "enum": [
                "A",
                "B",
                "C",
                "D",
                "E",
                "F",
                "G",
                "H",
                "I",
                "J",
                "K",
                "L",
                "M",
                "T",
                "X",
                "Z"
              ]
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SetChecklistTemplate"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ChecklistTemplate"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "settings:admin"
            ]
          }
        ],
        "summary": "Set the firm’s checklist for a section",
        "tags": [
          "Settings"
        ],
        "x-required-role": "admin",
        "x-required-scopes": [
          "settings:admin"
        ],
        "x-required-product": "working_papers"
      }
    },
    "/api/v1/clients/{clientId}/checklist-steps": {
      "get": {
        "operationId": "ClientChecklist_list",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "clientId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/ClientChecklistStep"
                  }
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "clients:read"
            ]
          }
        ],
        "summary": "List a client’s own checklist steps",
        "tags": [
          "Clients"
        ],
        "x-required-scopes": [
          "clients:read"
        ],
        "x-required-product": "working_papers",
        "description": "Scopes: `clients:read`. Part of the `working_papers` product: the firm must have it and you must have access to it."
      },
      "post": {
        "description": "Added to the section’s checklist on each new engagement.\n\nScopes: `clients:write`. Part of the `working_papers` product: the firm must have it and you must have access to it.",
        "operationId": "ClientChecklist_add",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "clientId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "A unique key (1-255 visible characters) to make retries safe. Replayed for 24 hours.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateClientChecklistStep"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ClientChecklistStep"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "A request with this Idempotency-Key is still being processed.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "422": {
            "description": "This Idempotency-Key was already used for a different request.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "clients:write"
            ]
          }
        ],
        "summary": "Add a checklist step for this client",
        "tags": [
          "Clients"
        ],
        "x-required-scopes": [
          "clients:write"
        ],
        "x-required-product": "working_papers"
      }
    },
    "/api/v1/settings": {
      "get": {
        "description": "Firm details, thresholds, reminders, default workflows, workflow templates, notifications, sync, security, capacity and AI.\n\nScopes: `settings:read`.",
        "operationId": "FirmSettings_all",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FirmSettings"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "settings:read"
            ]
          }
        ],
        "summary": "Get the firm’s settings",
        "tags": [
          "Settings"
        ],
        "x-required-scopes": [
          "settings:read"
        ]
      }
    },
    "/api/v1/settings/firm": {
      "patch": {
        "operationId": "FirmSettings_firm",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/FirmDetails"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FirmSettings"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Update the firm’s name, tagline and offices",
        "tags": [
          "Settings"
        ],
        "x-required-role": "admin",
        "x-required-scopes": [
          "settings:admin"
        ],
        "x-session-only": true,
        "description": "Firm admins only. Scopes: `settings:admin`. Only from a signed-in Tolvi session, never with an API token."
      }
    },
    "/api/v1/settings/thresholds": {
      "put": {
        "operationId": "FirmSettings_thresholds",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/FirmThresholds"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FirmSettings"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "settings:admin"
            ]
          }
        ],
        "summary": "Set the review thresholds new engagements use",
        "tags": [
          "Settings"
        ],
        "x-required-role": "admin",
        "x-required-scopes": [
          "settings:admin"
        ],
        "description": "Firm admins only. Scopes: `settings:admin`."
      }
    },
    "/api/v1/settings/approvals": {
      "put": {
        "description": "Firm admins, signed in. Partners by default, or managers and partners. Applies to Accounts, Corporation Tax and Self Assessment from the next approval, and approvals already given stand. Never available to API keys or connected assistants.\n\nFirm admins only. Scopes: `settings:admin`. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "FirmSettings_approvals",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ApprovalSettings"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FirmSettings"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Set who approves accounts and returns",
        "tags": [
          "Settings"
        ],
        "x-required-role": "admin",
        "x-required-scopes": [
          "settings:admin"
        ],
        "x-session-only": true
      }
    },
    "/api/v1/settings/reminders": {
      "put": {
        "operationId": "FirmSettings_reminders",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Reminders"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FirmSettings"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "settings:admin"
            ]
          }
        ],
        "summary": "Set deadline reminder days",
        "tags": [
          "Settings"
        ],
        "x-required-role": "admin",
        "x-required-scopes": [
          "settings:admin"
        ],
        "description": "Firm admins only. Scopes: `settings:admin`."
      }
    },
    "/api/v1/settings/default-workflows": {
      "put": {
        "operationId": "FirmSettings_defaults",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DefaultWorkflows"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FirmSettings"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Set the default workflow for each entity type",
        "tags": [
          "Settings"
        ],
        "x-required-role": "admin",
        "x-required-scopes": [
          "settings:admin"
        ],
        "x-session-only": true,
        "description": "Firm admins only. Scopes: `settings:admin`. Only from a signed-in Tolvi session, never with an API token."
      }
    },
    "/api/v1/settings/notifications": {
      "put": {
        "description": "Mentions and assignments always arrive in-app.\n\nFirm admins only. Scopes: `settings:admin`.",
        "operationId": "FirmSettings_notifications",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/NotificationPrefs"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FirmSettings"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "settings:admin"
            ]
          }
        ],
        "summary": "Set the firm’s notification channels",
        "tags": [
          "Settings"
        ],
        "x-required-role": "admin",
        "x-required-scopes": [
          "settings:admin"
        ]
      }
    },
    "/api/v1/settings/sync": {
      "put": {
        "operationId": "FirmSettings_sync",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SyncSettings"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FirmSettings"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "settings:admin"
            ]
          }
        ],
        "summary": "Set sync settings",
        "tags": [
          "Settings"
        ],
        "x-required-role": "admin",
        "x-required-scopes": [
          "settings:admin"
        ],
        "description": "Firm admins only. Scopes: `settings:admin`."
      }
    },
    "/api/v1/settings/email": {
      "put": {
        "description": "The firm’s time zone and the local hour the daily digest and deadline reminders go out.\n\nFirm admins only. Scopes: `settings:admin`.",
        "operationId": "FirmSettings_email",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EmailSettings"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FirmSettings"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "settings:admin"
            ]
          }
        ],
        "summary": "Set when digests and deadline reminders are emailed",
        "tags": [
          "Settings"
        ],
        "x-required-role": "admin",
        "x-required-scopes": [
          "settings:admin"
        ]
      }
    },
    "/api/v1/settings/security": {
      "put": {
        "operationId": "FirmSettings_security",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SecuritySettings"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FirmSettings"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Set security settings",
        "tags": [
          "Settings"
        ],
        "x-required-role": "admin",
        "x-required-scopes": [
          "settings:admin"
        ],
        "x-session-only": true,
        "description": "Firm admins only. Scopes: `settings:admin`. Only from a signed-in Tolvi session, never with an API token."
      }
    },
    "/api/v1/settings/capacity": {
      "put": {
        "operationId": "FirmSettings_capacity",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Capacity"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FirmSettings"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "settings:admin"
            ]
          }
        ],
        "summary": "Set capacity by role",
        "tags": [
          "Settings"
        ],
        "x-required-role": "admin",
        "x-required-scopes": [
          "settings:admin"
        ],
        "description": "Firm admins only. Scopes: `settings:admin`."
      }
    },
    "/api/v1/settings/ai": {
      "put": {
        "description": "On/off, per-feature switches, monthly limits, who can buy tokens and auto top-up.\n\nFirm admins only. Scopes: `settings:admin`. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "FirmSettings_ai",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AiSettings"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FirmSettings"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Set Tolvi AI controls",
        "tags": [
          "Settings"
        ],
        "x-required-role": "admin",
        "x-required-scopes": [
          "settings:admin"
        ],
        "x-session-only": true
      }
    },
    "/api/v1/settings/onboarding": {
      "get": {
        "operationId": "FirmSettings_onboarding",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OnboardingStatus"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "work:read"
            ]
          }
        ],
        "summary": "Get onboarding progress",
        "tags": [
          "Settings"
        ],
        "x-required-scopes": [
          "work:read"
        ],
        "description": "Scopes: `work:read`."
      },
      "post": {
        "description": "complete finishes first-run setup and clears its saved progress. skip (“Finish later”) lets the firm into Tolvi and keeps the progress, so setup resumes where it was left.\n\nFirm admins only. Scopes: `settings:admin`. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "FirmSettings_completeOnboarding",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CompleteOnboarding"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OnboardingStatus"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Complete or skip onboarding",
        "tags": [
          "Settings"
        ],
        "x-required-role": "admin",
        "x-required-scopes": [
          "settings:admin"
        ],
        "x-session-only": true
      }
    },
    "/api/v1/settings/onboarding/progress": {
      "get": {
        "description": "The step to resume at, how clients are being brought in and the invitations queued to send at the end. Firm admins, signed in to the web app.\n\nFirm admins only. Scopes: `settings:admin`. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "FirmSettings_onboardingProgress",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OnboardingProgress"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get first-run setup progress",
        "tags": [
          "Settings"
        ],
        "x-required-role": "admin",
        "x-required-scopes": [
          "settings:admin"
        ],
        "x-session-only": true
      },
      "put": {
        "description": "Saves the step reached and the invitations queued so far; nothing is sent. The invitations go out when setup finishes, one POST /invitations each. Firm admins, signed in to the web app.\n\nFirm admins only. Scopes: `settings:admin`. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "FirmSettings_saveOnboardingProgress",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SaveOnboardingProgress"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OnboardingProgress"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Save first-run setup progress",
        "tags": [
          "Settings"
        ],
        "x-required-role": "admin",
        "x-required-scopes": [
          "settings:admin"
        ],
        "x-session-only": true
      }
    },
    "/api/v1/settings/workflows": {
      "get": {
        "operationId": "FirmSettings_workflows",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/WorkflowTemplate"
                  }
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "settings:read"
            ]
          }
        ],
        "summary": "List workflow templates (presets and the firm’s own)",
        "tags": [
          "Settings"
        ],
        "x-required-scopes": [
          "settings:read"
        ],
        "description": "Scopes: `settings:read`."
      },
      "put": {
        "description": "Validated with @tolvi/workflow. Engagements already started keep the template they started with.\n\nFirm admins only. Scopes: `settings:admin`. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "FirmSettings_setWorkflows",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SetWorkflowTemplates"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/WorkflowTemplate"
                  }
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Replace the firm’s workflow templates",
        "tags": [
          "Settings"
        ],
        "x-required-role": "admin",
        "x-required-scopes": [
          "settings:admin"
        ],
        "x-session-only": true
      }
    },
    "/api/v1/members": {
      "get": {
        "operationId": "Members_list",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Member"
                  }
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "settings:read"
            ]
          }
        ],
        "summary": "List the firm’s people with their roles, capacity and open work",
        "tags": [
          "Settings"
        ],
        "x-required-scopes": [
          "settings:read"
        ],
        "description": "Scopes: `settings:read`."
      }
    },
    "/api/v1/members/{userId}": {
      "delete": {
        "description": "They lose access at once and leave the firm’s sign-in organisation. Only an owner can remove an owner; you can’t remove yourself.\n\nFirm admins only. Scopes: `settings:admin`. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "Members_remove",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "userId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Removed.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Remove someone from the firm",
        "tags": [
          "Settings"
        ],
        "x-required-role": "admin",
        "x-required-scopes": [
          "settings:admin"
        ],
        "x-session-only": true
      }
    },
    "/api/v1/clients/{clientId}": {
      "get": {
        "operationId": "ClientProfile_get",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "clientId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ClientDetail"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "clients:read"
            ]
          }
        ],
        "summary": "Get a client with its settings, notes and year-end history",
        "tags": [
          "Clients"
        ],
        "x-required-scopes": [
          "clients:read"
        ],
        "description": "Scopes: `clients:read`."
      }
    },
    "/api/v1/clients/{clientId}/mappings": {
      "get": {
        "description": "Changing an account’s mapping in section B remembers it for the client; next year it is applied ahead of the firm rules.\n\nScopes: `clients:read`.",
        "operationId": "ClientProfile_mappings",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "clientId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/ClientMapping"
                  }
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "clients:read"
            ]
          }
        ],
        "summary": "List the client’s remembered mappings",
        "tags": [
          "Clients"
        ],
        "x-required-scopes": [
          "clients:read"
        ]
      }
    },
    "/api/v1/clients/{clientId}/settings": {
      "get": {
        "operationId": "ClientProfile_settings",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "clientId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ClientOverrides"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "clients:read"
            ]
          }
        ],
        "summary": "Get the client’s overrides of the firm settings",
        "tags": [
          "Clients"
        ],
        "x-required-scopes": [
          "clients:read"
        ],
        "description": "Scopes: `clients:read`."
      },
      "patch": {
        "description": "Send only what changes; null goes back to the firm default. Used by engagements started from now on.\n\nNeeds the Manager role or above. Scopes: `clients:write`.",
        "operationId": "ClientProfile_setSettings",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "clientId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ClientOverrides"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ClientOverrides"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "clients:write"
            ]
          }
        ],
        "summary": "Change the client’s overrides",
        "tags": [
          "Clients"
        ],
        "x-required-role": "manager",
        "x-required-scopes": [
          "clients:write"
        ]
      }
    },
    "/api/v1/clients/{clientId}/notes": {
      "get": {
        "operationId": "ClientProfile_notes",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "clientId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ClientNotes"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "clients:read"
            ]
          }
        ],
        "summary": "Get the client’s permanent notes",
        "tags": [
          "Clients"
        ],
        "x-required-scopes": [
          "clients:read"
        ],
        "description": "Scopes: `clients:read`."
      },
      "patch": {
        "operationId": "ClientProfile_setNotes",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "clientId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SetClientNotes"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ClientNotes"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "clients:write"
            ]
          }
        ],
        "summary": "Replace the client’s permanent notes",
        "tags": [
          "Clients"
        ],
        "x-required-scopes": [
          "clients:write"
        ],
        "description": "Scopes: `clients:write`."
      }
    },
    "/api/v1/integrations/providers": {
      "get": {
        "description": "Which providers this Tolvi deployment is set up for (developer app credentials present), and this firm’s connections to each by status.\n\nScopes: `clients:read`.",
        "operationId": "Integrations_providers",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/IntegrationProviders"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "clients:read"
            ]
          }
        ],
        "summary": "List bookkeeping providers",
        "tags": [
          "Integrations"
        ],
        "x-required-scopes": [
          "clients:read"
        ]
      }
    },
    "/api/v1/integrations/callback": {
      "post": {
        "description": "Called by the web app’s /integrations/callback/{provider} page with the code and state from the provider’s redirect, as the signed-in user who started the connect. The state is single-use and expires after 10 minutes. With one organisation it is bound at once; with several, choose one with PUT /clients/{clientId}/connection/organisation. A practice connect (POST /integrations/practice/authorize) is refused with 409 and its state left unused: finish it with POST /integrations/practice/callback.\n\nScopes: `integrations:manage`. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "Integrations_callback",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/IntegrationCallbackRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/IntegrationCallbackResult"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Finish connecting a client’s books",
        "tags": [
          "Integrations"
        ],
        "x-required-scopes": [
          "integrations:manage"
        ],
        "x-session-only": true
      }
    },
    "/api/v1/integrations/practice/authorize": {
      "post": {
        "description": "Returns Xero’s sign-in URL. The adviser ticks every client organisation to bring in (Xero lets one sign-in cover several). Xero returns them to /integrations/callback/xero, and POST /integrations/practice/callback stores one authorisation for them all.\n\nScopes: `integrations:manage`, `clients:write`. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "PracticeImport_authorize",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AuthorizePracticeRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AuthorizeConnectionResult"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Start importing clients from Xero",
        "tags": [
          "Integrations"
        ],
        "x-required-scopes": [
          "integrations:manage",
          "clients:write"
        ],
        "x-session-only": true
      }
    },
    "/api/v1/integrations/practice/callback": {
      "post": {
        "description": "Called by the web app’s /integrations/callback/{provider} page with the code and state from Xero’s redirect, as the signed-in user who started the import (POST /integrations/practice/authorize). The state is single-use and expires after 10 minutes. Stores one authorisation for every organisation the adviser ticked and returns its grantId; nothing is imported until POST /integrations/practice/grants/{grantId}/import. A client’s connect is refused with 409 and its state left unused: finish it with POST /integrations/callback.\n\nScopes: `integrations:manage`, `clients:write`. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "PracticeImport_callback",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PracticeCallbackRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PracticeCallbackResult"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Finish importing clients from Xero",
        "tags": [
          "Integrations"
        ],
        "x-required-scopes": [
          "integrations:manage",
          "clients:write"
        ],
        "x-session-only": true
      }
    },
    "/api/v1/integrations/practice/grants": {
      "get": {
        "description": "This firm’s Xero authorisations for importing clients, newest first. Tokens are never returned.\n\nScopes: `integrations:manage`.",
        "operationId": "PracticeImport_grants",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PracticeGrantList"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "integrations:manage"
            ]
          }
        ],
        "summary": "List practice authorisations",
        "tags": [
          "Integrations"
        ],
        "x-required-scopes": [
          "integrations:manage"
        ]
      }
    },
    "/api/v1/integrations/practice/grants/{grantId}/organisations": {
      "get": {
        "description": "Each organisation the adviser authorised, as Xero describes it (name, legal form, Companies House and VAT numbers, financial year end), with the suggested entity type, the next year end, and whether it is already in Tolvi (matched by company number, then name) or already connected.\n\nScopes: `integrations:manage`.",
        "operationId": "PracticeImport_organisations",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "grantId",
            "required": true,
            "in": "path",
            "description": "Practice authorisation id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PracticeOrganisationList"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "integrations:manage"
            ]
          }
        ],
        "summary": "List the organisations to import",
        "tags": [
          "Integrations"
        ],
        "x-required-scopes": [
          "integrations:manage"
        ]
      }
    },
    "/api/v1/integrations/practice/grants/{grantId}/import": {
      "post": {
        "description": "Creates a client for each chosen organisation, or links it to the client it matches (company number, then name; never a duplicate), sets the year end, and connects the client’s books through this authorisation so the trial balance can be pulled without connecting again. Organisations already connected, or matching a client connected to other books, are reported and left alone.\n\nScopes: `integrations:manage`, `clients:write`.",
        "operationId": "PracticeImport_import",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "grantId",
            "required": true,
            "in": "path",
            "description": "Practice authorisation id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "A unique key (1-255 visible characters) to make retries safe. Replayed for 24 hours.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PracticeImportRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PracticeImportResult"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "A request with this Idempotency-Key is still being processed.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "422": {
            "description": "This Idempotency-Key was already used for a different request.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "integrations:manage",
              "clients:write"
            ]
          }
        ],
        "summary": "Import clients from Xero",
        "tags": [
          "Integrations"
        ],
        "x-required-scopes": [
          "integrations:manage",
          "clients:write"
        ]
      }
    },
    "/api/v1/integrations/practice/grants/{grantId}": {
      "delete": {
        "description": "Revokes it at Xero and disconnects every client connected through it (their open engagements go back to manual). Clients and imported trial balances are kept.\n\nScopes: `integrations:manage`.",
        "operationId": "PracticeImport_remove",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "grantId",
            "required": true,
            "in": "path",
            "description": "Practice authorisation id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "integrations:manage"
            ]
          }
        ],
        "summary": "Remove a practice authorisation",
        "tags": [
          "Integrations"
        ],
        "x-required-scopes": [
          "integrations:manage"
        ]
      }
    },
    "/api/v1/clients/{clientId}/connection": {
      "get": {
        "description": "Status, organisation and when the books were last read. Tokens are never returned.\n\nScopes: `clients:read`.",
        "operationId": "ClientConnection_get",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "clientId",
            "required": true,
            "in": "path",
            "description": "Client id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ClientConnection"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "clients:read"
            ]
          }
        ],
        "summary": "Get a client’s bookkeeping connection",
        "tags": [
          "Integrations"
        ],
        "x-required-scopes": [
          "clients:read"
        ]
      },
      "delete": {
        "description": "Revokes Tolvi’s access at the provider where it supports that (Xero, QuickBooks, Sage; for FreeAgent remove the app there), then forgets the connection. Imported trial balances are kept.\n\nScopes: `integrations:manage`.",
        "operationId": "ClientConnection_disconnect",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "clientId",
            "required": true,
            "in": "path",
            "description": "Client id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "integrations:manage"
            ]
          }
        ],
        "summary": "Disconnect a client’s books",
        "tags": [
          "Integrations"
        ],
        "x-required-scopes": [
          "integrations:manage"
        ]
      }
    },
    "/api/v1/clients/{clientId}/connection/authorize": {
      "post": {
        "description": "Returns the provider’s sign-in URL to send the user to. Reconnecting replaces the current connection once the user completes it.\n\nScopes: `integrations:manage`. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "ClientConnection_authorize",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "clientId",
            "required": true,
            "in": "path",
            "description": "Client id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AuthorizeConnectionRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AuthorizeConnectionResult"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Start connecting a client’s books",
        "tags": [
          "Integrations"
        ],
        "x-required-scopes": [
          "integrations:manage"
        ],
        "x-session-only": true
      }
    },
    "/api/v1/clients/{clientId}/connection/organisation": {
      "put": {
        "description": "One of the organisations the connection was authorised for.\n\nScopes: `integrations:manage`. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "ClientConnection_organisation",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "clientId",
            "required": true,
            "in": "path",
            "description": "Client id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ChooseOrganisationRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ClientConnection"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Choose the client’s organisation",
        "tags": [
          "Integrations"
        ],
        "x-required-scopes": [
          "integrations:manage"
        ],
        "x-session-only": true
      }
    },
    "/api/v1/engagements/{id}/tb/pull": {
      "get": {
        "description": "The source a pull for this engagement reads, without reading it: an engagement keeps the source it is on (its Work queue software); a new one reads the client’s Tolvi Books when linked, else its OAuth connection. Switch an engagement’s source on the client’s Connection tab (PUT /clients/{clientId}/books-link/engagements).\n\nScopes: `engagements:read`. Part of the `working_papers` product: the firm must have it and you must have access to it.",
        "operationId": "TbPull_source",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Engagement id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TbPullSource"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "engagements:read"
            ]
          }
        ],
        "summary": "Get where the trial balance would be pulled from",
        "tags": [
          "Engagements"
        ],
        "x-required-scopes": [
          "engagements:read"
        ],
        "x-required-product": "working_papers"
      },
      "post": {
        "description": "Pulls again and adds a new immutable trial balance version, exactly as a CSV import would (mappings remembered, journals on missing accounts removed only with confirmJournalRemoval). Send the preview’s hash as expectedHash to refuse (409) if the books changed in between. 409 also when the connection needs reconnecting.\n\nScopes: `engagements:write`, `engagements:read`. Part of the `working_papers` product: the firm must have it and you must have access to it.",
        "operationId": "TbPull_pull",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Engagement id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "A unique key (1-255 visible characters) to make retries safe. Replayed for 24 hours.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TbPullRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TbImportResult"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "A request with this Idempotency-Key is still being processed.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "422": {
            "description": "This Idempotency-Key was already used for a different request.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "engagements:write",
              "engagements:read"
            ]
          }
        ],
        "summary": "Pull the trial balance from the bookkeeping software",
        "tags": [
          "Engagements"
        ],
        "x-required-scopes": [
          "engagements:write",
          "engagements:read"
        ],
        "x-required-product": "working_papers"
      }
    },
    "/api/v1/engagements/{id}/tb/pull/preview": {
      "post": {
        "description": "Reads the TB at the period end (and at the prior period end for the prior year column) from the client’s connection, or from the client’s Tolvi Books through the firm’s practice link (both columns at one ledger point, already mapped by the books’ lead lines). Nothing is stored. Same shape as the CSV import preview, plus where it came from.\n\nScopes: `engagements:write`, `engagements:read`. Part of the `working_papers` product: the firm must have it and you must have access to it.",
        "operationId": "TbPull_preview",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Engagement id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TbPullPreview"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "engagements:write",
              "engagements:read"
            ]
          }
        ],
        "summary": "Preview pulling the trial balance from the bookkeeping software",
        "tags": [
          "Engagements"
        ],
        "x-required-scopes": [
          "engagements:write",
          "engagements:read"
        ],
        "x-required-product": "working_papers"
      }
    },
    "/api/v1/clients/{clientId}/chart-of-accounts": {
      "get": {
        "description": "Every account in the client’s books, with or without a balance (the trial balance lists only accounts with balances), as last read from their bookkeeping software or imported from a CSV, with the lead schedule line each would map to. Section C and journals offer these real nominal codes.\n\nScopes: `clients:read`.",
        "operationId": "ClientChartOfAccounts_get",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "clientId",
            "required": true,
            "in": "path",
            "description": "Client id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ChartOfAccounts"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "clients:read"
            ]
          }
        ],
        "summary": "Get a client’s chart of accounts",
        "tags": [
          "Integrations"
        ],
        "x-required-scopes": [
          "clients:read"
        ]
      },
      "put": {
        "description": "For a client whose books are not connected: replaces the stored chart with the file’s accounts. The file needs Code and Name columns; Type and Status are read where present (Xero’s chart of accounts export works as it is). 422 with the reason when the file can’t be read.\n\nScopes: `clients:write`.",
        "operationId": "ClientChartOfAccounts_import",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "clientId",
            "required": true,
            "in": "path",
            "description": "Client id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ImportChartOfAccountsRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ChartOfAccounts"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "clients:write"
            ]
          }
        ],
        "summary": "Import a client’s chart of accounts from a CSV",
        "tags": [
          "Integrations"
        ],
        "x-required-scopes": [
          "clients:write"
        ]
      }
    },
    "/api/v1/clients/{clientId}/chart-of-accounts/refresh": {
      "post": {
        "description": "Reads the chart from the client’s connected books and replaces the stored one. Tolvi also does this when the books are connected and on every trial balance pull. 409 when the books are not connected or the connection needs reconnecting.\n\nScopes: `clients:write`.",
        "operationId": "ClientChartOfAccounts_refresh",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "clientId",
            "required": true,
            "in": "path",
            "description": "Client id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ChartOfAccounts"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "clients:write"
            ]
          }
        ],
        "summary": "Read a client’s chart of accounts again",
        "tags": [
          "Integrations"
        ],
        "x-required-scopes": [
          "clients:write"
        ]
      }
    },
    "/api/v1/sync": {
      "get": {
        "description": "Counts by sync state (open engagements, plus completed ones the sign-off check still covers), the last and any running sign-off check, the schedule and rules, and counts by software.\n\nScopes: `work:read`. Part of the `working_papers` product: the firm must have it and you must have access to it.",
        "operationId": "Sync_overview",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SyncOverview"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "work:read"
            ]
          }
        ],
        "summary": "Sync health overview",
        "tags": [
          "Sync health"
        ],
        "x-required-scopes": [
          "work:read"
        ],
        "x-required-product": "working_papers"
      }
    },
    "/api/v1/sync/engagements": {
      "get": {
        "description": "Earliest deadline first, each with its latest sign-off check result.\n\nScopes: `work:read`. Part of the `working_papers` product: the firm must have it and you must have access to it.",
        "operationId": "Sync_list",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 500,
              "default": 100
            }
          },
          {
            "name": "includeCompleted",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "true",
                "false"
              ]
            },
            "description": "changed only: include completed engagements."
          },
          {
            "name": "list",
            "required": false,
            "in": "query",
            "description": "changed (default), fix (reconnect or fix), manual (open manual uploads), resolved (today).",
            "schema": {
              "enum": [
                "changed",
                "fix",
                "manual",
                "resolved"
              ],
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SyncRowPage"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "work:read"
            ]
          }
        ],
        "summary": "List engagements for Sync health",
        "tags": [
          "Sync health"
        ],
        "x-required-scopes": [
          "work:read"
        ],
        "x-required-product": "working_papers"
      }
    },
    "/api/v1/sync/runs": {
      "post": {
        "description": "Starts a check of every connected engagement with a sign-off (or only engagementIds). The books are read in the background; poll GET /sync/runs/{id}. A run already in progress is returned instead of starting another.\n\nScopes: `engagements:write`. Part of the `working_papers` product: the firm must have it and you must have access to it.",
        "operationId": "Sync_start",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "A unique key (1-255 visible characters) to make retries safe. Replayed for 24 hours.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            }
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/StartSyncCheckRequest"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SyncCheckRun"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "A request with this Idempotency-Key is still being processed.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "422": {
            "description": "This Idempotency-Key was already used for a different request.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "engagements:write"
            ]
          }
        ],
        "summary": "Run the sign-off check now",
        "tags": [
          "Sync health"
        ],
        "x-required-scopes": [
          "engagements:write"
        ],
        "x-required-product": "working_papers"
      }
    },
    "/api/v1/sync/reminders": {
      "post": {
        "description": "For engagements whose connection has expired, failed or never synced: tells the preparer (else the manager, else the partner) which clients need reconnecting, in the app and by email unless they have turned those emails off. One reminder per person. You are never reminded yourself.\n\nScopes: `engagements:write`. Part of the `working_papers` product: the firm must have it and you must have access to it.",
        "operationId": "Sync_remind",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "A unique key (1-255 visible characters) to make retries safe. Replayed for 24 hours.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SyncRemindersRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SyncReminders"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "A request with this Idempotency-Key is still being processed.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "422": {
            "description": "This Idempotency-Key was already used for a different request.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "engagements:write"
            ]
          }
        ],
        "summary": "Remind people to reconnect bookkeeping",
        "tags": [
          "Sync health"
        ],
        "x-required-scopes": [
          "engagements:write"
        ],
        "x-required-product": "working_papers"
      }
    },
    "/api/v1/sync/runs/{id}": {
      "get": {
        "operationId": "Sync_run",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Run id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SyncCheckRun"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "work:read"
            ]
          }
        ],
        "summary": "Get a sign-off check run",
        "tags": [
          "Sync health"
        ],
        "x-required-scopes": [
          "work:read"
        ],
        "x-required-product": "working_papers",
        "description": "Scopes: `work:read`. Part of the `working_papers` product: the firm must have it and you must have access to it."
      }
    },
    "/api/v1/engagements/{id}/sync-check": {
      "get": {
        "description": "The latest result: account-by-account differences from the signed-off trial balance, the transactions behind them and the affected sections, with the engagement’s earlier resolutions.\n\nScopes: `engagements:read`. Part of the `working_papers` product: the firm must have it and you must have access to it.",
        "operationId": "EngagementSync_get",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Engagement id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SyncCheckDetail"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "engagements:read"
            ]
          }
        ],
        "summary": "Get an engagement’s sign-off check",
        "tags": [
          "Sync health"
        ],
        "x-required-scopes": [
          "engagements:read"
        ],
        "x-required-product": "working_papers"
      }
    },
    "/api/v1/engagements/{id}/sync-check/accept": {
      "post": {
        "description": "Pulls the books again into a new immutable trial balance version and reopens the affected sections; their sign-offs go stale through the content fingerprint (a new amendment round). 409 if there is no open change, or if journals would be removed without confirmJournalRemoval.\n\nScopes: `engagements:write`. Part of the `working_papers` product: the firm must have it and you must have access to it.",
        "operationId": "EngagementSync_accept",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Engagement id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "A unique key (1-255 visible characters) to make retries safe. Replayed for 24 hours.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            }
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AcceptSyncChangeRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SyncCheckDetail"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "A request with this Idempotency-Key is still being processed.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "422": {
            "description": "This Idempotency-Key was already used for a different request.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "engagements:write"
            ]
          }
        ],
        "summary": "Accept and re-sync",
        "tags": [
          "Sync health"
        ],
        "x-required-scopes": [
          "engagements:write"
        ],
        "x-required-product": "working_papers"
      }
    },
    "/api/v1/engagements/{id}/sync-check/acknowledge": {
      "post": {
        "description": "Records why no action is needed (a note is required for “Other”). The same differences are not raised again by later checks.\n\nScopes: `review:write`. Part of the `working_papers` product: the firm must have it and you must have access to it.",
        "operationId": "EngagementSync_acknowledge",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Engagement id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AcknowledgeSyncChangeRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SyncCheckDetail"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "review:write"
            ]
          }
        ],
        "summary": "Acknowledge a change without re-syncing",
        "tags": [
          "Sync health"
        ],
        "x-required-scopes": [
          "review:write"
        ],
        "x-required-product": "working_papers"
      }
    },
    "/api/v1/engagements/{id}/sync-check/post-filing": {
      "post": {
        "description": "For a completed engagement: records the change as a post-filing change (tell the client; consider amended accounts or next year’s opening balances). The same differences are not raised again.\n\nScopes: `review:write`. Part of the `working_papers` product: the firm must have it and you must have access to it.",
        "operationId": "EngagementSync_postFiling",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Engagement id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PostFilingChangeRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SyncCheckDetail"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "review:write"
            ]
          }
        ],
        "summary": "Record a post-filing change",
        "tags": [
          "Sync health"
        ],
        "x-required-scopes": [
          "review:write"
        ],
        "x-required-product": "working_papers"
      }
    },
    "/api/v1/engagements/{id}/exports": {
      "post": {
        "description": "Queues a PDF of the whole file: cover with sign-off summary, index, every section in order (lead schedule, variance notes, tickmarks with legend, checklist, reconciliations, review point threads, sign-offs), journals, tax computation, draft accounts, review history and an appendix of evidence files with checksums. Rendering happens in the background: poll the export until it is ready. While one is queued or rendering, that one is returned. Optionally choose the sections and leave out the evidence appendix, the review point threads or the review history; the cover then says what was left out. A file that is not fully signed off prints with a “Draft – not signed off” banner.\n\nScopes: `engagements:read`. Part of the `working_papers` product: the firm must have it and you must have access to it.",
        "operationId": "Exports_request",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Engagement id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "A unique key (1-255 visible characters) to make retries safe. Replayed for 24 hours.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            }
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WorkingPaperExportOptions"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WorkingPaperExport"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "A request with this Idempotency-Key is still being processed.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "422": {
            "description": "This Idempotency-Key was already used for a different request.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "engagements:read"
            ]
          }
        ],
        "summary": "Export the working paper file",
        "tags": [
          "Working paper file"
        ],
        "x-required-scopes": [
          "engagements:read"
        ],
        "x-required-product": "working_papers"
      },
      "get": {
        "operationId": "Exports_list",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Engagement id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/WorkingPaperExport"
                  }
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "engagements:read"
            ]
          }
        ],
        "summary": "List the engagement’s working paper file exports, newest first",
        "tags": [
          "Working paper file"
        ],
        "x-required-scopes": [
          "engagements:read"
        ],
        "x-required-product": "working_papers",
        "description": "Scopes: `engagements:read`. Part of the `working_papers` product: the firm must have it and you must have access to it."
      }
    },
    "/api/v1/engagements/{id}/exports/{exportId}": {
      "get": {
        "operationId": "Exports_get",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Engagement id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "exportId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WorkingPaperExport"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "engagements:read"
            ]
          }
        ],
        "summary": "Get one export (poll this while it renders)",
        "tags": [
          "Working paper file"
        ],
        "x-required-scopes": [
          "engagements:read"
        ],
        "x-required-product": "working_papers",
        "description": "Scopes: `engagements:read`. Part of the `working_papers` product: the firm must have it and you must have access to it."
      }
    },
    "/api/v1/engagements/{id}/exports/{exportId}/download": {
      "get": {
        "description": "409 while it is still rendering, or if it failed.\n\nScopes: `engagements:read`. Part of the `working_papers` product: the firm must have it and you must have access to it.",
        "operationId": "Exports_download",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Engagement id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "exportId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PresignedUpload"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "engagements:read"
            ]
          }
        ],
        "summary": "Get a short-lived download URL for a ready export",
        "tags": [
          "Working paper file"
        ],
        "x-required-scopes": [
          "engagements:read"
        ],
        "x-required-product": "working_papers"
      }
    },
    "/api/v1/ai/balance": {
      "get": {
        "operationId": "Ai_balance",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AiBalance"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "engagements:read"
            ]
          }
        ],
        "summary": "Get the firm’s token balance, expiry and this month’s use",
        "tags": [
          "Tolvi AI"
        ],
        "x-required-scopes": [
          "engagements:read"
        ],
        "description": "Scopes: `engagements:read`."
      }
    },
    "/api/v1/ai/usage": {
      "get": {
        "operationId": "Ai_usage",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "groupBy",
            "required": false,
            "in": "query",
            "schema": {
              "$ref": "#/components/schemas/AiUsageGroupBy"
            }
          },
          {
            "name": "from",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "to",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AiUsage"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "engagements:read"
            ]
          }
        ],
        "summary": "Token use by month, person, feature, engagement or model, with recent ledger entries",
        "tags": [
          "Tolvi AI"
        ],
        "x-required-scopes": [
          "engagements:read"
        ],
        "description": "Scopes: `engagements:read`."
      }
    },
    "/api/v1/ai/packs": {
      "get": {
        "description": "VAT is 0 and gross equals net while Tolvi is not VAT-registered (vatRegistered false).\n\nScopes: `engagements:read`.",
        "operationId": "Ai_packs",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AiPacks"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "engagements:read"
            ]
          }
        ],
        "summary": "List the token packs and prices (net, VAT, gross in pence)",
        "tags": [
          "Tolvi AI"
        ],
        "x-required-scopes": [
          "engagements:read"
        ]
      }
    },
    "/api/v1/ai/checkout": {
      "post": {
        "description": "Partners and admins (or admins only, per the firm’s AI settings). The tokens are credited when Stripe confirms payment.\n\nScopes: `settings:admin`, `engagements:read`. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "Ai_checkout",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AiCheckoutRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AiCheckout"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Buy a token pack (Stripe Checkout)",
        "tags": [
          "Tolvi AI"
        ],
        "x-required-scopes": [
          "settings:admin",
          "engagements:read"
        ],
        "x-session-only": true
      }
    },
    "/api/v1/ai/suggestions": {
      "get": {
        "operationId": "Ai_suggestions",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "engagementId",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/AiSuggestion"
                  }
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "engagements:read"
            ]
          }
        ],
        "summary": "List recent AI suggestions",
        "tags": [
          "Tolvi AI"
        ],
        "x-required-scopes": [
          "engagements:read"
        ],
        "description": "Scopes: `engagements:read`."
      }
    },
    "/api/v1/ai/suggestions/{id}": {
      "get": {
        "operationId": "Ai_suggestion",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AiSuggestion"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "engagements:read"
            ]
          }
        ],
        "summary": "Get an AI suggestion",
        "tags": [
          "Tolvi AI"
        ],
        "x-required-scopes": [
          "engagements:read"
        ],
        "description": "Scopes: `engagements:read`."
      }
    },
    "/api/v1/ai/suggestions/{id}/accept": {
      "post": {
        "description": "Records the decision; the person then applies it (e.g. saves the note) through the normal endpoints.\n\nScopes: `engagements:write`, `engagements:read`.",
        "operationId": "Ai_accept",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AiSuggestion"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "engagements:write",
              "engagements:read"
            ]
          }
        ],
        "summary": "Accept an AI suggestion",
        "tags": [
          "Tolvi AI"
        ],
        "x-required-scopes": [
          "engagements:write",
          "engagements:read"
        ]
      }
    },
    "/api/v1/ai/suggestions/{id}/discard": {
      "post": {
        "operationId": "Ai_discard",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AiSuggestion"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "engagements:write",
              "engagements:read"
            ]
          }
        ],
        "summary": "Discard an AI suggestion",
        "tags": [
          "Tolvi AI"
        ],
        "x-required-scopes": [
          "engagements:write",
          "engagements:read"
        ],
        "description": "Scopes: `engagements:write`, `engagements:read`."
      }
    },
    "/api/v1/ai/{feature}": {
      "post": {
        "description": "Estimate → reserve → run → settle against the firm’s token ledger. Returns a suggestion (status proposed). With estimateOnly, returns the estimate instead (AiEstimate). 402 when the balance cannot cover the estimate; 403 when the feature is off or your monthly limit is used.\n\nScopes: `engagements:write`, `engagements:read`.",
        "operationId": "Ai_run",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "feature",
            "required": true,
            "in": "path",
            "schema": {
              "$ref": "#/components/schemas/AiFeature"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "A unique key (1-255 visible characters) to make retries safe. Replayed for 24 hours.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AiRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/AiSuggestion"
                    },
                    {
                      "$ref": "#/components/schemas/AiEstimate"
                    }
                  ]
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "A request with this Idempotency-Key is still being processed.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "422": {
            "description": "This Idempotency-Key was already used for a different request.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "engagements:write",
              "engagements:read"
            ]
          }
        ],
        "summary": "Run a Tolvi AI feature",
        "tags": [
          "Tolvi AI"
        ],
        "x-required-scopes": [
          "engagements:write",
          "engagements:read"
        ]
      }
    },
    "/api/v1/billing/account": {
      "get": {
        "operationId": "Billing_account",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BillingAccount"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "settings:admin"
            ]
          }
        ],
        "summary": "Get the firm’s billing account, plan and this period’s engagements",
        "tags": [
          "Billing"
        ],
        "x-required-role": "admin",
        "x-required-scopes": [
          "settings:admin"
        ],
        "description": "Firm admins only. Scopes: `settings:admin`."
      }
    },
    "/api/v1/billing/plan": {
      "get": {
        "description": "Graduated monthly tiers, as data.\n\nFirm admins only. Scopes: `settings:admin`.",
        "operationId": "Billing_plan",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BillingPlan"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "settings:admin"
            ]
          }
        ],
        "summary": "Get the per-engagement tiers the plans are priced from",
        "tags": [
          "Billing"
        ],
        "x-required-role": "admin",
        "x-required-scopes": [
          "settings:admin"
        ]
      }
    },
    "/api/v1/billing/plans": {
      "get": {
        "operationId": "Billing_plans",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PlanCatalogue"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "settings:admin"
            ]
          }
        ],
        "summary": "List the plans with monthly and annual prices, allowances, AI tokens, overage rates and entitlements",
        "tags": [
          "Billing"
        ],
        "x-required-role": "admin",
        "x-required-scopes": [
          "settings:admin"
        ],
        "description": "Firm admins only. Scopes: `settings:admin`."
      }
    },
    "/api/v1/billing/subscription": {
      "get": {
        "operationId": "Billing_subscription",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Subscription"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "settings:admin"
            ]
          }
        ],
        "summary": "Get the subscription: plan, interval, allowance used this plan year, AI tokens this month, next invoice, entitlements",
        "tags": [
          "Billing"
        ],
        "x-required-role": "admin",
        "x-required-scopes": [
          "settings:admin"
        ],
        "description": "Firm admins only. Scopes: `settings:admin`."
      },
      "post": {
        "description": "A first plan starts the subscription and plan year. Upgrades apply at once, prorated; downgrades are scheduled for renewal. Clears a pending cancellation.\n\nFirm admins only. Scopes: `settings:admin`. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "Billing_change",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ChangePlan"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Subscription"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Choose or change plan",
        "tags": [
          "Billing"
        ],
        "x-required-role": "admin",
        "x-required-scopes": [
          "settings:admin"
        ],
        "x-session-only": true
      }
    },
    "/api/v1/billing/subscription/preview": {
      "post": {
        "description": "Upgrades apply now, prorated; downgrades at renewal.\n\nFirm admins only. Scopes: `settings:admin`.",
        "operationId": "Billing_preview",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ChangePlan"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PlanChangePreview"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "settings:admin"
            ]
          }
        ],
        "summary": "Preview a plan change",
        "tags": [
          "Billing"
        ],
        "x-required-role": "admin",
        "x-required-scopes": [
          "settings:admin"
        ]
      }
    },
    "/api/v1/billing/meetings": {
      "get": {
        "operationId": "Billing_meetings",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MeetingsBilling"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "settings:admin"
            ]
          }
        ],
        "summary": "Get the Meetings tiers, the firm’s Meetings plan and this month’s minutes",
        "tags": [
          "Billing"
        ],
        "x-required-role": "admin",
        "x-required-scopes": [
          "settings:admin"
        ],
        "description": "Firm admins only. Scopes: `settings:admin`."
      },
      "put": {
        "description": "With a Tolvi subscription, Meetings is added to it at its interval: a first plan and upgrades apply at once, prorated, once the invoice is paid; downgrades and cancelling (planId null) apply at the end of the billing period. Without one, Meetings is bought on its own through Stripe Checkout (`interval` month or year; see pendingCheckoutUrl) and starts once the first invoice is paid.\n\nFirm admins only. Scopes: `settings:admin`. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "Billing_changeMeetings",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ChangeMeetingsPlan"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MeetingsBilling"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Choose, change or cancel the Meetings plan",
        "tags": [
          "Billing"
        ],
        "x-required-role": "admin",
        "x-required-scopes": [
          "settings:admin"
        ],
        "x-session-only": true
      }
    },
    "/api/v1/billing/subscription/cancel": {
      "post": {
        "description": "Monthly plans: one month’s notice. Annual plans: at renewal (no refund).\n\nFirm admins only. Scopes: `settings:admin`. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "Billing_cancel",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Subscription"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Cancel the subscription",
        "tags": [
          "Billing"
        ],
        "x-required-role": "admin",
        "x-required-scopes": [
          "settings:admin"
        ],
        "x-session-only": true
      }
    },
    "/api/v1/billing/subscription/resume": {
      "post": {
        "operationId": "Billing_resume",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Subscription"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Keep a subscription that is set to cancel",
        "tags": [
          "Billing"
        ],
        "x-required-role": "admin",
        "x-required-scopes": [
          "settings:admin"
        ],
        "x-session-only": true,
        "description": "Firm admins only. Scopes: `settings:admin`. Only from a signed-in Tolvi session, never with an API token."
      }
    },
    "/api/v1/billing/usage": {
      "get": {
        "operationId": "Billing_usage",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "from",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "to",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BillingUsage"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "settings:admin"
            ]
          }
        ],
        "summary": "List billable engagements (started and credited) in a period (default: this month)",
        "tags": [
          "Billing"
        ],
        "x-required-role": "admin",
        "x-required-scopes": [
          "settings:admin"
        ],
        "description": "Firm admins only. Scopes: `settings:admin`."
      }
    },
    "/api/v1/billing/invoices": {
      "get": {
        "operationId": "Billing_invoices",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Invoice"
                  }
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "settings:admin"
            ]
          }
        ],
        "summary": "List invoices (Stripe-hosted)",
        "tags": [
          "Billing"
        ],
        "x-required-role": "admin",
        "x-required-scopes": [
          "settings:admin"
        ],
        "description": "Firm admins only. Scopes: `settings:admin`."
      }
    },
    "/api/v1/billing/setup": {
      "post": {
        "description": "Choose a plan with POST /billing/subscription; add a payment method in the Customer Portal.\n\nFirm admins only. Scopes: `settings:admin`. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "Billing_setup",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BillingSetup"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BillingAccount"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Set billing details (contact, VAT number) and create the Stripe customer",
        "tags": [
          "Billing"
        ],
        "x-required-role": "admin",
        "x-required-scopes": [
          "settings:admin"
        ],
        "x-session-only": true
      }
    },
    "/api/v1/billing/portal": {
      "post": {
        "operationId": "Billing_portal",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PortalSession"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Open the Stripe Customer Portal (payment method, billing details, invoices)",
        "tags": [
          "Billing"
        ],
        "x-required-role": "admin",
        "x-required-scopes": [
          "settings:admin"
        ],
        "x-session-only": true,
        "description": "Firm admins only. Scopes: `settings:admin`. Only from a signed-in Tolvi session, never with an API token."
      }
    },
    "/api/v1/billing/start-status": {
      "get": {
        "description": "The same gate as starting (402 when blocked): trial’s free engagements used or the trial over without a plan, or an invoice unpaid for 14 days. Viewing and exports are never blocked.\n\nScopes: `engagements:write`.",
        "operationId": "EngagementStartStatus_get",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EngagementStartStatus"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "engagements:write"
            ]
          }
        ],
        "summary": "Check whether new engagements can start",
        "tags": [
          "Billing"
        ],
        "x-required-scopes": [
          "engagements:write"
        ]
      }
    },
    "/api/v1/books/billing": {
      "get": {
        "description": "How Tolvi Books is paid for (a trial, the business, or its accountant), the tier the business needs, the tiers with monthly and annual prices, and this month’s AI fair use. Owners and admins.\n\nScopes: `books:admin`.",
        "operationId": "BooksBilling_get",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BooksBilling"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:admin"
            ]
          }
        ],
        "summary": "Get the business’s Tolvi Books plan and the tiers",
        "tags": [
          "Billing"
        ],
        "x-required-scopes": [
          "books:admin"
        ]
      }
    },
    "/api/v1/books/billing/plan": {
      "put": {
        "description": "Without a plan: Stripe Checkout (interval month or year; see pendingCheckoutUrl), and Tolvi Books is paid for once the first invoice is. With one: upgrades apply at once, prorated, once paid; downgrades and cancelling (planId null) at the end of the billing period. The current plan with another interval switches how it is billed: to year at once, prorated, once paid; to month at the end of the billing period. The tier must be at least requiredPlanId. Refused (409) while the business’s accountant pays. Signed-in owners and admins only.\n\nScopes: `books:admin`. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "BooksBilling_change",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ChangeBooksPlan"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BooksBilling"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Choose, change or cancel the business’s Tolvi Books plan",
        "tags": [
          "Billing"
        ],
        "x-required-scopes": [
          "books:admin"
        ],
        "x-session-only": true
      }
    },
    "/api/v1/books/billing/portal": {
      "post": {
        "description": "Payment method, billing details and invoices. Signed-in owners and admins only.\n\nScopes: `books:admin`. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "BooksBilling_portal",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BooksPortalSession"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Open the Stripe Customer Portal for the business",
        "tags": [
          "Billing"
        ],
        "x-required-scopes": [
          "books:admin"
        ],
        "x-session-only": true
      }
    },
    "/api/v1/practice/books/billing": {
      "get": {
        "description": "Every business with a live link, the tier it needs, the wholesale price and whether the firm pays.\n\nFirm admins only. Scopes: `settings:admin`.",
        "operationId": "PracticeBooksBilling_get",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PracticeBooksBilling"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "settings:admin"
            ]
          }
        ],
        "summary": "List the firm’s Tolvi Books clients and whose Books it pays for",
        "tags": [
          "Billing"
        ],
        "x-required-role": "admin",
        "x-required-scopes": [
          "settings:admin"
        ]
      }
    },
    "/api/v1/practice/books/billing/clients/{linkId}": {
      "post": {
        "description": "Adds the client to the firm’s Tolvi invoice at the wholesale price for the tier it needs, prorated, from today (`agree: true` records the firm admin’s agreement to the client’s consentText). Paid for once that invoice is paid. A firm with no Tolvi subscription gets a Stripe Checkout for Tolvi Books alone (see pendingCheckoutUrl); the client starts once its first invoice is paid. Needs a live link; refused (409) if the business already pays for itself, or while another Checkout is unfinished.\n\nFirm admins only. Scopes: `settings:admin`. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "PracticeBooksBilling_pay",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "linkId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "A unique key (1-255 visible characters) to make retries safe. Replayed for 24 hours.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PayForClientBooks"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PracticeBooksBilling"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "A request with this Idempotency-Key is still being processed.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "422": {
            "description": "This Idempotency-Key was already used for a different request.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Pay for a client’s Tolvi Books",
        "tags": [
          "Billing"
        ],
        "x-required-role": "admin",
        "x-required-scopes": [
          "settings:admin"
        ],
        "x-session-only": true
      }
    },
    "/api/v1/practice/books/billing/clients/{linkId}/stop": {
      "post": {
        "description": "Takes the client off the firm’s invoice now (credited, prorated). The business keeps its books and gets a grace period before it must choose a plan of its own.\n\nFirm admins only. Scopes: `settings:admin`. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "PracticeBooksBilling_stop",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "linkId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/StopPayingForClientBooks"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PracticeBooksBilling"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Stop paying for a client’s Tolvi Books",
        "tags": [
          "Billing"
        ],
        "x-required-role": "admin",
        "x-required-scopes": [
          "settings:admin"
        ],
        "x-session-only": true
      }
    },
    "/api/v1/email-preferences": {
      "get": {
        "operationId": "EmailPreferences_get",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EmailPreferences"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "work:read"
            ]
          }
        ],
        "summary": "Get your email preferences",
        "tags": [
          "Notifications"
        ],
        "x-required-scopes": [
          "work:read"
        ],
        "description": "Scopes: `work:read`."
      },
      "put": {
        "operationId": "EmailPreferences_set",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EmailPreferencesPatch"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EmailPreferences"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "work:read"
            ]
          }
        ],
        "summary": "Change your email preferences",
        "tags": [
          "Notifications"
        ],
        "x-required-scopes": [
          "work:read"
        ],
        "description": "Scopes: `work:read`."
      }
    },
    "/api/v1/email/preferences": {
      "get": {
        "description": "No sign-in: the token in the link identifies the firm and person.",
        "operationId": "EmailLinks_get",
        "parameters": [
          {
            "name": "token",
            "required": true,
            "in": "query",
            "description": "The signed token from the link in an email.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EmailLinkPreferences"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "summary": "Get email preferences from an email link",
        "tags": [
          "Notifications"
        ]
      },
      "put": {
        "operationId": "EmailLinks_set",
        "parameters": [
          {
            "name": "token",
            "required": true,
            "in": "query",
            "description": "The signed token from the link in an email.",
            "schema": {}
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EmailPreferencesPatch"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EmailLinkPreferences"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "summary": "Change email preferences from an email link",
        "tags": [
          "Notifications"
        ]
      }
    },
    "/api/v1/email/unsubscribe": {
      "post": {
        "description": "The List-Unsubscribe target. Mail clients POST `List-Unsubscribe=One-Click`; the body is not needed.",
        "operationId": "EmailLinks_unsubscribe",
        "parameters": [
          {
            "name": "token",
            "required": true,
            "in": "query",
            "description": "The signed token from the link in an email.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EmailLinkPreferences"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "summary": "One-click unsubscribe (RFC 8058)",
        "tags": [
          "Notifications"
        ]
      }
    },
    "/api/v1/webhooks/event-types": {
      "get": {
        "description": "The event catalogue you can subscribe to.\n\nFirm admins only. Scopes: `webhooks:manage`.",
        "operationId": "Webhooks_eventTypes",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/WebhookEventTypeInfo"
                  }
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "webhooks:manage"
            ]
          }
        ],
        "summary": "List the webhook event types",
        "tags": [
          "Webhooks"
        ],
        "x-required-role": "admin",
        "x-required-scopes": [
          "webhooks:manage"
        ]
      }
    },
    "/api/v1/webhooks": {
      "get": {
        "operationId": "Webhooks_list",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/WebhookSubscription"
                  }
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "webhooks:manage"
            ]
          }
        ],
        "summary": "List webhook subscriptions",
        "tags": [
          "Webhooks"
        ],
        "x-required-role": "admin",
        "x-required-scopes": [
          "webhooks:manage"
        ],
        "description": "Firm admins only. Scopes: `webhooks:manage`."
      },
      "post": {
        "description": "Returns the signing secret once. Each delivery is a POST with a JSON body and a `Tolvi-Signature: t=<unix seconds>,v1=<hex>` header, where v1 is HMAC-SHA256 of `<t>.<raw body>` keyed with the subscription’s secret. Reject a delivery whose signature does not match or whose t is more than 5 minutes from now, and de-duplicate on `Tolvi-Event-Id`. Answer 2xx within 10 seconds; anything else is retried with exponential backoff (30 s doubling to 6 h, 12 attempts). After 20 failed attempts in a row the subscription is disabled and the firm’s admins are told.\n\nFirm admins only. Scopes: `webhooks:manage`.",
        "operationId": "Webhooks_create",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateWebhookSubscription"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreatedWebhookSubscription"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "webhooks:manage"
            ]
          }
        ],
        "summary": "Create a webhook subscription",
        "tags": [
          "Webhooks"
        ],
        "x-required-role": "admin",
        "x-required-scopes": [
          "webhooks:manage"
        ]
      }
    },
    "/api/v1/webhooks/{id}": {
      "get": {
        "operationId": "Webhooks_get",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Webhook subscription id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookSubscription"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "webhooks:manage"
            ]
          }
        ],
        "summary": "Get a webhook subscription",
        "tags": [
          "Webhooks"
        ],
        "x-required-role": "admin",
        "x-required-scopes": [
          "webhooks:manage"
        ],
        "description": "Firm admins only. Scopes: `webhooks:manage`."
      },
      "patch": {
        "description": "Change the URL, event types or description, or disable it. Setting status to `active` re-enables a disabled subscription and resets its failure count.\n\nFirm admins only. Scopes: `webhooks:manage`.",
        "operationId": "Webhooks_update",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Webhook subscription id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateWebhookSubscription"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookSubscription"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "webhooks:manage"
            ]
          }
        ],
        "summary": "Update a webhook subscription",
        "tags": [
          "Webhooks"
        ],
        "x-required-role": "admin",
        "x-required-scopes": [
          "webhooks:manage"
        ]
      },
      "delete": {
        "description": "Deletes it with its delivery log. Pending deliveries are not sent.\n\nFirm admins only. Scopes: `webhooks:manage`.",
        "operationId": "Webhooks_remove",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Webhook subscription id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "webhooks:manage"
            ]
          }
        ],
        "summary": "Delete a webhook subscription",
        "tags": [
          "Webhooks"
        ],
        "x-required-role": "admin",
        "x-required-scopes": [
          "webhooks:manage"
        ]
      }
    },
    "/api/v1/webhooks/test": {
      "post": {
        "description": "Before subscribing: checks the URL as a subscription would (https, public addresses only) and POSTs one `ping` event to it, then says what came back. The test is signed with a one-off key, so your endpoint can’t verify its signature; it only needs to answer 2xx within 10 seconds. Nothing is stored or retried.\n\nFirm admins only. Scopes: `webhooks:manage`.",
        "operationId": "Webhooks_test",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TestWebhookEndpoint"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookEndpointTest"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "webhooks:manage"
            ]
          }
        ],
        "summary": "Send a test event to an endpoint",
        "tags": [
          "Webhooks"
        ],
        "x-required-role": "admin",
        "x-required-scopes": [
          "webhooks:manage"
        ]
      }
    },
    "/api/v1/webhooks/{id}/rotate-secret": {
      "post": {
        "description": "Returns the new secret once. The old one stops working at once, including for retries already scheduled.\n\nFirm admins only. Scopes: `webhooks:manage`.",
        "operationId": "Webhooks_rotateSecret",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Webhook subscription id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreatedWebhookSubscription"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "webhooks:manage"
            ]
          }
        ],
        "summary": "Rotate the signing secret",
        "tags": [
          "Webhooks"
        ],
        "x-required-role": "admin",
        "x-required-scopes": [
          "webhooks:manage"
        ]
      }
    },
    "/api/v1/webhooks/{id}/deliveries": {
      "get": {
        "description": "The delivery log: status, attempts and the last response code.\n\nFirm admins only. Scopes: `webhooks:manage`.",
        "operationId": "Webhooks_deliveries",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Webhook subscription id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "cursor",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "status",
            "required": false,
            "in": "query",
            "schema": {
              "$ref": "#/components/schemas/WebhookDeliveryStatus"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookDeliveryPage"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "webhooks:manage"
            ]
          }
        ],
        "summary": "List a subscription’s deliveries, newest first",
        "tags": [
          "Webhooks"
        ],
        "x-required-role": "admin",
        "x-required-scopes": [
          "webhooks:manage"
        ]
      }
    },
    "/api/v1/webhooks/{id}/deliveries/{deliveryId}": {
      "get": {
        "operationId": "Webhooks_delivery",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Webhook subscription id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "deliveryId",
            "required": true,
            "in": "path",
            "description": "Delivery id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookDeliveryDetail"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "webhooks:manage"
            ]
          }
        ],
        "summary": "Get a delivery with its payload and every attempt",
        "tags": [
          "Webhooks"
        ],
        "x-required-role": "admin",
        "x-required-scopes": [
          "webhooks:manage"
        ],
        "description": "Firm admins only. Scopes: `webhooks:manage`."
      }
    },
    "/api/v1/webhooks/{id}/deliveries/{deliveryId}/replay": {
      "post": {
        "description": "Queues the same event again as a new delivery, sent within seconds. The event id is unchanged, so receivers that de-duplicate on it ignore a copy they already processed.\n\nFirm admins only. Scopes: `webhooks:manage`.",
        "operationId": "Webhooks_replay",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Webhook subscription id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "deliveryId",
            "required": true,
            "in": "path",
            "description": "Delivery id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "A unique key (1-255 visible characters) to make retries safe. Replayed for 24 hours.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            }
          }
        ],
        "responses": {
          "202": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookDelivery"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "A request with this Idempotency-Key is still being processed.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "422": {
            "description": "This Idempotency-Key was already used for a different request.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "webhooks:manage"
            ]
          }
        ],
        "summary": "Replay a delivery",
        "tags": [
          "Webhooks"
        ],
        "x-required-role": "admin",
        "x-required-scopes": [
          "webhooks:manage"
        ]
      }
    },
    "/api/v1/me/tour-state": {
      "get": {
        "description": "Not started until you first open the tour.\n\nScopes: `work:read`.",
        "operationId": "TourState_get",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "product",
            "required": false,
            "in": "query",
            "description": "Which product’s tour: each has its own short one. Defaults to working_papers, the original welcome tour.",
            "schema": {
              "$ref": "#/components/schemas/TourProduct"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TourState"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "work:read"
            ]
          }
        ],
        "summary": "Get your welcome tour progress",
        "tags": [
          "Getting started"
        ],
        "x-required-scopes": [
          "work:read"
        ]
      },
      "put": {
        "description": "Only the fields sent are changed.\n\nScopes: `work:read`.",
        "operationId": "TourState_set",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "product",
            "required": false,
            "in": "query",
            "description": "Which product’s tour: each has its own short one. Defaults to working_papers, the original welcome tour.",
            "schema": {
              "$ref": "#/components/schemas/TourProduct"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TourStatePatch"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TourState"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "work:read"
            ]
          }
        ],
        "summary": "Save your welcome tour progress",
        "tags": [
          "Getting started"
        ],
        "x-required-scopes": [
          "work:read"
        ]
      }
    },
    "/api/v1/search": {
      "get": {
        "description": "Matches part of a name (or a Companies House number for clients and engagements), a few per group, best matches first. A group is searched only when you may read it: engagements need engagements:read and Working Papers; sections need an `engagementId` as well; meetings need meetings:read and Meetings; people need settings:read. Read-only, and limited like every other read.\n\nScopes: `clients:read`.",
        "operationId": "Search_search",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "description": "Most results per group.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 20,
              "default": 5
            }
          },
          {
            "name": "engagementId",
            "required": false,
            "in": "query",
            "description": "Also search the sections of this engagement.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "q",
            "required": true,
            "in": "query",
            "description": "What to look for.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 100
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SearchResults"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "clients:read"
            ]
          }
        ],
        "summary": "Search clients, engagements, sections, meetings and people",
        "tags": [
          "Suite"
        ],
        "x-required-scopes": [
          "clients:read"
        ]
      }
    },
    "/api/v1/products": {
      "get": {
        "description": "The catalogue, whether or not your firm has each one.\n\nScopes: `work:read`.",
        "operationId": "Products_list",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Product"
                  }
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "work:read"
            ]
          }
        ],
        "summary": "List the products in the Tolvi suite",
        "tags": [
          "Suite"
        ],
        "x-required-scopes": [
          "work:read"
        ]
      }
    },
    "/api/v1/me/products": {
      "get": {
        "description": "What the app switcher shows. A product the firm has only for people given access is listed only if you have been.\n\nScopes: `work:read`.",
        "operationId": "MyProducts_list",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/MyProduct"
                  }
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "work:read"
            ]
          }
        ],
        "summary": "List the products you can open in this firm",
        "tags": [
          "Suite"
        ],
        "x-required-scopes": [
          "work:read"
        ]
      }
    },
    "/api/v1/firm/products": {
      "get": {
        "description": "With status, access mode, trial end and how many people can use each.\n\nScopes: `work:read`.",
        "operationId": "FirmProducts_list",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/FirmProduct"
                  }
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "work:read"
            ]
          }
        ],
        "summary": "List the products your firm has",
        "tags": [
          "Suite"
        ],
        "x-required-scopes": [
          "work:read"
        ]
      }
    },
    "/api/v1/firm/products/{key}": {
      "post": {
        "description": "Only for products the catalogue marks self-serve. You are given access to it straight away.\n\nFirm admins only. Scopes: `settings:admin`, `work:read`. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "FirmProducts_start",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "key",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "pattern": "^[a-z][a-z0-9_]{1,39}$"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "A unique key (1-255 visible characters) to make retries safe. Replayed for 24 hours.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            }
          }
        ],
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FirmProduct"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "A request with this Idempotency-Key is still being processed.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "422": {
            "description": "This Idempotency-Key was already used for a different request.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Start a trial of a product",
        "tags": [
          "Suite"
        ],
        "x-required-role": "admin",
        "x-required-scopes": [
          "settings:admin",
          "work:read"
        ],
        "x-session-only": true
      },
      "patch": {
        "description": "everyone: every member of the firm. assigned: only people given access (their grants are kept either way).\n\nFirm admins only. Scopes: `settings:admin`, `work:read`. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "FirmProducts_update",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "key",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "pattern": "^[a-z][a-z0-9_]{1,39}$"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/FirmProductPatch"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FirmProduct"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Change who can use a product",
        "tags": [
          "Suite"
        ],
        "x-required-role": "admin",
        "x-required-scopes": [
          "settings:admin",
          "work:read"
        ],
        "x-session-only": true
      }
    },
    "/api/v1/product-access": {
      "get": {
        "description": "The firm’s products, and for each person which they can use and which they have been given.\n\nFirm admins only. Scopes: `settings:admin`.",
        "operationId": "ProductAccess_matrix",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProductAccessMatrix"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "settings:admin"
            ]
          }
        ],
        "summary": "Get the people × products view",
        "tags": [
          "Suite"
        ],
        "x-required-role": "admin",
        "x-required-scopes": [
          "settings:admin"
        ]
      }
    },
    "/api/v1/product-access/{key}/members/{userId}": {
      "put": {
        "description": "Idempotent. Takes effect at once.\n\nFirm admins only. Scopes: `settings:admin`, `settings:admin`. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "ProductAccess_grant",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "key",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "pattern": "^[a-z][a-z0-9_]{1,39}$"
            }
          },
          {
            "name": "userId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "They have access.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Give someone access to a product",
        "tags": [
          "Suite"
        ],
        "x-required-role": "admin",
        "x-required-scopes": [
          "settings:admin",
          "settings:admin"
        ],
        "x-session-only": true
      },
      "delete": {
        "description": "Idempotent. In everyone mode they keep using it until the mode is assigned.\n\nFirm admins only. Scopes: `settings:admin`, `settings:admin`. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "ProductAccess_revoke",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "key",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "pattern": "^[a-z][a-z0-9_]{1,39}$"
            }
          },
          {
            "name": "userId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "They no longer have it.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Take away someone’s access to a product",
        "tags": [
          "Suite"
        ],
        "x-required-role": "admin",
        "x-required-scopes": [
          "settings:admin",
          "settings:admin"
        ],
        "x-session-only": true
      }
    },
    "/api/v1/meetings": {
      "get": {
        "description": "Newest first (up to 200). Filter by client to see the meetings filed against it, by words in the title or client name, by status, or to the ones you sent.\n\nScopes: `meetings:read`. Part of the `meetings` product: the firm must have it and you must have access to it.",
        "operationId": "Meetings_list",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "mine",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "true",
                "false"
              ]
            },
            "description": "true: only the meetings you sent a note-taker to."
          },
          {
            "name": "status",
            "required": false,
            "in": "query",
            "description": "upcoming (scheduling, scheduled), in_progress (joining to processing), ready, not_recorded (failed or cancelled).",
            "schema": {
              "$ref": "#/components/schemas/MeetingStatusGroup"
            }
          },
          {
            "name": "q",
            "required": false,
            "in": "query",
            "description": "Words in the meeting’s title or its client’s name.",
            "schema": {
              "type": "string",
              "maxLength": 100
            }
          },
          {
            "name": "clientId",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/MeetingSummary"
                  }
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "meetings:read"
            ]
          }
        ],
        "summary": "List meetings",
        "tags": [
          "Meetings"
        ],
        "x-required-scopes": [
          "meetings:read"
        ],
        "x-required-product": "meetings"
      },
      "post": {
        "description": "Recall.ai joins the meeting at joinAt (now if left out) as a visible participant, posts a notice that it is recording, and records it. After the call Tolvi files the transcript and Tolvi AI’s summary and actions against the meeting (charged to you as AI tokens). 409 if someone in the firm already sent one to the same meeting; 502 if Recall refused it.\n\nScopes: `meetings:write`. Part of the `meetings` product: the firm must have it and you must have access to it.",
        "operationId": "Meetings_launch",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "A unique key (1-255 visible characters) to make retries safe. Replayed for 24 hours.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LaunchMeetingRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MeetingDetail"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "A request with this Idempotency-Key is still being processed.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "422": {
            "description": "This Idempotency-Key was already used for a different request.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "meetings:write"
            ]
          }
        ],
        "summary": "Send a note-taker to a meeting",
        "tags": [
          "Meetings"
        ],
        "x-required-scopes": [
          "meetings:write"
        ],
        "x-required-product": "meetings"
      }
    },
    "/api/v1/meetings/usage": {
      "get": {
        "description": "Each meeting counts its recording’s length, rounded up to the minute, in the month it started.\n\nScopes: `meetings:read`. Part of the `meetings` product: the firm must have it and you must have access to it.",
        "operationId": "Meetings_usage",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MeetingsUsage"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "meetings:read"
            ]
          }
        ],
        "summary": "Get this month’s recorded minutes against the firm’s allowance",
        "tags": [
          "Meetings"
        ],
        "x-required-scopes": [
          "meetings:read"
        ],
        "x-required-product": "meetings"
      }
    },
    "/api/v1/meetings/{id}": {
      "get": {
        "operationId": "Meetings_get",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MeetingDetail"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "meetings:read"
            ]
          }
        ],
        "summary": "Get a meeting with its transcript, summary and actions",
        "tags": [
          "Meetings"
        ],
        "x-required-scopes": [
          "meetings:read"
        ],
        "x-required-product": "meetings",
        "description": "Scopes: `meetings:read`. Part of the `meetings` product: the firm must have it and you must have access to it."
      },
      "patch": {
        "operationId": "Meetings_update",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateMeetingRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MeetingDetail"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "meetings:write"
            ]
          }
        ],
        "summary": "Rename a meeting or file it against a client",
        "tags": [
          "Meetings"
        ],
        "x-required-scopes": [
          "meetings:write"
        ],
        "x-required-product": "meetings",
        "description": "Scopes: `meetings:write`. Part of the `meetings` product: the firm must have it and you must have access to it."
      }
    },
    "/api/v1/meetings/{id}/follow-ups": {
      "post": {
        "description": "For a filed meeting with a ready write-up: each chosen next step becomes a review point on one of the client’s engagements (needs a reviewer, manager or partner, the review:write scope and Working Papers), a request listed in the follow-up email, or is skipped. Review points are raised exactly as in the engagement, with the meeting as their source. A step already sorted the same way is left alone; sorting it differently is refused (409). Nothing is signed off.\n\nScopes: `meetings:write`. Part of the `meetings` product: the firm must have it and you must have access to it.",
        "operationId": "Meetings_followUps",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "A unique key (1-255 visible characters) to make retries safe. Replayed for 24 hours.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateMeetingFollowUpsRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MeetingDetail"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "A request with this Idempotency-Key is still being processed.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "422": {
            "description": "This Idempotency-Key was already used for a different request.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "meetings:write"
            ]
          }
        ],
        "summary": "Turn next steps into follow-ups",
        "tags": [
          "Meetings"
        ],
        "x-required-scopes": [
          "meetings:write"
        ],
        "x-required-product": "meetings"
      }
    },
    "/api/v1/meetings/{id}/cancel": {
      "post": {
        "description": "Before it joins, it is cancelled. In the call, it leaves and what it recorded so far is still transcribed.\n\nScopes: `meetings:write`. Part of the `meetings` product: the firm must have it and you must have access to it.",
        "operationId": "Meetings_cancel",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MeetingDetail"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "meetings:write"
            ]
          }
        ],
        "summary": "Stop the note-taker",
        "tags": [
          "Meetings"
        ],
        "x-required-scopes": [
          "meetings:write"
        ],
        "x-required-product": "meetings"
      }
    },
    "/api/v1/me/calendar": {
      "get": {
        "description": "The next 28 days. A note-taker joins only the meetings you tick. Each event says if a colleague already sent a note-taker to it, and suggests a client whose name is in its title.\n\nScopes: `meetings:read`. Part of the `meetings` product: the firm must have it and you must have access to it.",
        "operationId": "MyCalendar_get",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MyCalendar"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "meetings:read"
            ]
          }
        ],
        "summary": "Get your connected calendar and its upcoming meetings",
        "tags": [
          "Meetings"
        ],
        "x-required-scopes": [
          "meetings:read"
        ],
        "x-required-product": "meetings"
      },
      "delete": {
        "description": "Note-takers scheduled from it are cancelled.\n\nScopes: `meetings:write`. Part of the `meetings` product: the firm must have it and you must have access to it. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "MyCalendar_disconnect",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Disconnected.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Disconnect your calendar",
        "tags": [
          "Meetings"
        ],
        "x-required-scopes": [
          "meetings:write"
        ],
        "x-required-product": "meetings",
        "x-session-only": true
      }
    },
    "/api/v1/me/calendar/connect": {
      "post": {
        "description": "Returns Microsoft’s sign-in URL. Tolvi asks only to read your calendar.\n\nScopes: `meetings:write`. Part of the `meetings` product: the firm must have it and you must have access to it. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "MyCalendar_connect",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CalendarConnectStart"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Start connecting your Outlook calendar",
        "tags": [
          "Meetings"
        ],
        "x-required-scopes": [
          "meetings:write"
        ],
        "x-required-product": "meetings",
        "x-session-only": true
      }
    },
    "/api/v1/me/calendar/events/{eventId}/notetaker": {
      "put": {
        "description": "It joins when the meeting starts and follows the meeting if it moves.\n\nScopes: `meetings:write`. Part of the `meetings` product: the firm must have it and you must have access to it.",
        "operationId": "MyCalendar_add",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "eventId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "The calendar event id from GET /me/calendar."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CalendarNotetakerRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MeetingDetail"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "meetings:write"
            ]
          }
        ],
        "summary": "Send a note-taker to a calendar meeting",
        "tags": [
          "Meetings"
        ],
        "x-required-scopes": [
          "meetings:write"
        ],
        "x-required-product": "meetings"
      },
      "delete": {
        "operationId": "MyCalendar_remove",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "eventId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "The calendar event id from GET /me/calendar."
          }
        ],
        "responses": {
          "204": {
            "description": "It won’t join.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "meetings:write"
            ]
          }
        ],
        "summary": "Stop sending a note-taker to a calendar meeting",
        "tags": [
          "Meetings"
        ],
        "x-required-scopes": [
          "meetings:write"
        ],
        "x-required-product": "meetings",
        "description": "Scopes: `meetings:write`. Part of the `meetings` product: the firm must have it and you must have access to it."
      }
    },
    "/api/v1/books/signup": {
      "post": {
        "description": "Creates the business and emails a single-use link to the address given. Following it confirms the address, has the person choose a password in the Tolvi Books app and makes them the business’s owner. No token needed.",
        "operationId": "BooksSignup_create",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BooksSignUp"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SignUpResult"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Sign-up is closed: people join by invitation (TOLVI_SIGNUP_OPEN is off).",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "summary": "Sign a business up to Tolvi Books",
        "tags": [
          "Books"
        ]
      }
    },
    "/api/v1/books/business": {
      "get": {
        "description": "Anyone who can read the books, including a linked accountant.\n\nScopes: `books:read`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "Business_get",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Business"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:read"
            ]
          }
        ],
        "summary": "Get the business’s profile",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:read"
        ],
        "x-required-product": "books"
      },
      "patch": {
        "description": "The business’s owners and admins (books:admin). A practice that set the business up can too, through its link, until the owner joins. Changing VAT details needs a signed-in person.\n\nScopes: `books:write`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "Business_update",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateBusiness"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Business"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:write"
            ]
          }
        ],
        "summary": "Change the business’s details",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:write"
        ],
        "x-required-product": "books"
      }
    },
    "/api/v1/books/accountants": {
      "get": {
        "description": "Every practice link, live or ended. A linked accountant sees only their own firm’s link.\n\nScopes: `books:read`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "BusinessAccountants_list",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/PracticeLink"
                  }
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:read"
            ]
          }
        ],
        "summary": "List the business’s accountants",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:read"
        ],
        "x-required-product": "books"
      }
    },
    "/api/v1/books/accountants/invitations": {
      "post": {
        "description": "Emails a single-use link to the accountant, who accepts while signed in to their practice. Signed-in owners and admins only.\n\nScopes: `books:admin`. Part of the `books` product: the firm must have it and you must have access to it. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "BusinessAccountants_invite",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "A unique key (1-255 visible characters) to make retries safe. Replayed for 24 hours.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/InviteAccountant"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PracticeLink"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "A request with this Idempotency-Key is still being processed.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "422": {
            "description": "This Idempotency-Key was already used for a different request.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Invite an accountant",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:admin"
        ],
        "x-required-product": "books",
        "x-session-only": true
      }
    },
    "/api/v1/books/accountants/{linkId}": {
      "patch": {
        "description": "Access level, VAT agent (one practice at a time) and who pays.\n\nScopes: `books:admin`. Part of the `books` product: the firm must have it and you must have access to it. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "BusinessAccountants_change",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "linkId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ChangePracticeLink"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PracticeLink"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Change an accountant’s access",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:admin"
        ],
        "x-required-product": "books",
        "x-session-only": true
      }
    },
    "/api/v1/books/accountants/{linkId}/end": {
      "post": {
        "description": "Takes effect from their next request, in the database itself. Also withdraws an invitation. An ended link is never active again. Allowed even while Tolvi Books is suspended.\n\nScopes: `books:admin`. Part of the `books` product: the firm must have it and you must have access to it. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "BusinessAccountants_end",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "linkId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EndPracticeLink"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PracticeLink"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "End an accountant’s access",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:admin"
        ],
        "x-required-product": "books",
        "x-session-only": true
      }
    },
    "/api/v1/books/accountants/requests": {
      "get": {
        "description": "Requests sent to your verified email address, waiting for an answer.\n\nScopes: `books:admin`. Part of the `books` product: the firm must have it and you must have access to it. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "BusinessAccountants_requests",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/PracticeLink"
                  }
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List practices’ requests for access",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:admin"
        ],
        "x-required-product": "books",
        "x-session-only": true
      }
    },
    "/api/v1/books/accountants/requests/{linkId}/approve": {
      "post": {
        "description": "Links the practice to this business with the access you choose.\n\nScopes: `books:admin`. Part of the `books` product: the firm must have it and you must have access to it. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "BusinessAccountants_approve",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "linkId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ApprovePracticeLinkRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PracticeLink"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Approve a practice’s request",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:admin"
        ],
        "x-required-product": "books",
        "x-session-only": true
      }
    },
    "/api/v1/books/accountants/requests/{linkId}/decline": {
      "post": {
        "operationId": "BusinessAccountants_decline",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "linkId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PracticeLink"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Decline a practice’s request",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:admin"
        ],
        "x-required-product": "books",
        "x-session-only": true,
        "description": "Scopes: `books:admin`. Part of the `books` product: the firm must have it and you must have access to it. Only from a signed-in Tolvi session, never with an API token."
      }
    },
    "/api/v1/practice/books/links": {
      "get": {
        "description": "Requests, accepted invitations, live and ended links.\n\nScopes: `client_books:read`.",
        "operationId": "PracticeBooks_links",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/PracticeLink"
                  }
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "client_books:read"
            ]
          }
        ],
        "summary": "List the firm’s links to businesses’ books",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "client_books:read"
        ]
      }
    },
    "/api/v1/practice/books/requests": {
      "post": {
        "description": "Emails the owner, who approves or declines in Tolvi Books.\n\nScopes: `client_books:read`. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "PracticeBooks_request",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "A unique key (1-255 visible characters) to make retries safe. Replayed for 24 hours.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RequestBooksAccess"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PracticeLink"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "A request with this Idempotency-Key is still being processed.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "422": {
            "description": "This Idempotency-Key was already used for a different request.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Ask a business for access to its books",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "client_books:read"
        ],
        "x-session-only": true
      }
    },
    "/api/v1/practice/books/link-invitations/preview": {
      "post": {
        "description": "The token from the email, in the body (never the URL).\n\nScopes: `client_books:read`. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "PracticeBooks_preview",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PracticeLinkToken"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PracticeLinkInvitationPreview"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "See what a business’s invitation offers",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "client_books:read"
        ],
        "x-session-only": true
      }
    },
    "/api/v1/practice/books/link-invitations/accept": {
      "post": {
        "description": "The person it was emailed to accepts, signed in to their practice. Single use.\n\nScopes: `client_books:read`. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "PracticeBooks_accept",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PracticeLinkToken"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PracticeLink"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Accept a business’s invitation",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "client_books:read"
        ],
        "x-session-only": true
      }
    },
    "/api/v1/practice/books/links/{linkId}/end": {
      "post": {
        "description": "Also withdraws a request. An ended link is never active again.\n\nScopes: `client_books:read`. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "PracticeBooks_end",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "linkId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EndPracticeLink"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PracticeLink"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "End the firm’s access to a business’s books",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "client_books:read"
        ],
        "x-session-only": true
      }
    },
    "/api/v1/practice/books/businesses": {
      "post": {
        "description": "Creates the business with the firm as its accountant (full bookkeeping) under the firm’s engagement letter. The firm looks after it until the owner joins.\n\nScopes: `client_books:read`. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "PracticeBooks_provision",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "A unique key (1-255 visible characters) to make retries safe. Replayed for 24 hours.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ProvisionBusiness"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProvisionedBusiness"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "A request with this Idempotency-Key is still being processed.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "422": {
            "description": "This Idempotency-Key was already used for a different request.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Set Tolvi Books up for a client",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "client_books:read"
        ],
        "x-session-only": true
      }
    },
    "/api/v1/practice/books/businesses/{businessId}/owner-invitation": {
      "post": {
        "description": "Only while the firm still looks after it (before an owner has joined).\n\nScopes: `client_books:read`. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "PracticeBooks_inviteOwner",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "businessId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/OwnerInvitation"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OwnerInvitation"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Invite the owner of a business the firm set up",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "client_books:read"
        ],
        "x-session-only": true
      }
    },
    "/api/v1/clients/{clientId}/books-link": {
      "get": {
        "description": "Which business’s Tolvi Books is this client’s, the practice link’s status and access, which source its engagements pull the trial balance from (or that someone must choose, when it also has an OAuth connection), and the books at a glance (read through the link).\n\nScopes: `clients:read`.",
        "operationId": "ClientBooksLink_get",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "clientId",
            "required": true,
            "in": "path",
            "description": "Client id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ClientBooksLink"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "clients:read"
            ]
          }
        ],
        "summary": "Get a client’s link to Tolvi Books",
        "tags": [
          "Integrations"
        ],
        "x-required-scopes": [
          "clients:read"
        ]
      },
      "put": {
        "description": "Through one of the firm’s active practice links (the business grants it). One client per business; relinking replaces the client’s earlier link.\n\nScopes: `integrations:manage`. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "ClientBooksLink_link",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "clientId",
            "required": true,
            "in": "path",
            "description": "Client id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LinkClientBooks"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ClientBooksLink"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Link a client to a business’s Tolvi Books",
        "tags": [
          "Integrations"
        ],
        "x-required-scopes": [
          "integrations:manage"
        ],
        "x-session-only": true
      },
      "delete": {
        "description": "Forgets which business’s books this client is. The practice link itself is unchanged: end it under Clients’ books.\n\nScopes: `integrations:manage`. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "ClientBooksLink_unlink",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "clientId",
            "required": true,
            "in": "path",
            "description": "Client id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Unlink a client from Tolvi Books",
        "tags": [
          "Integrations"
        ],
        "x-required-scopes": [
          "integrations:manage"
        ],
        "x-session-only": true
      }
    },
    "/api/v1/clients/{clientId}/books-link/candidates": {
      "get": {
        "description": "Every business that has granted the firm an active link, with the client each is already linked to. Those named like this client and not yet linked are suggested.\n\nScopes: `clients:read`, `client_books:read`.",
        "operationId": "ClientBooksLink_candidates",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "clientId",
            "required": true,
            "in": "path",
            "description": "Client id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BooksLinkCandidateList"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "clients:read",
              "client_books:read"
            ]
          }
        ],
        "summary": "List businesses’ books this client could be linked to",
        "tags": [
          "Integrations"
        ],
        "x-required-scopes": [
          "clients:read",
          "client_books:read"
        ]
      }
    },
    "/api/v1/clients/{clientId}/books-link/source": {
      "put": {
        "description": "For a client with both an OAuth connection and a Tolvi Books link: whether its engagements pull the trial balance from its Tolvi Books (`tolvi_books`) or its OAuth connection (`connection`). Tolvi never chooses itself: until someone does, pulls are refused (409) with a request to choose. Stored on the client and can be changed later; open engagements follow, each shown as not yet read until its next pull. 409 when the client doesn’t have both, or the chosen one can’t be read.\n\nScopes: `integrations:manage`. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "ClientBooksLink_chooseSource",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "clientId",
            "required": true,
            "in": "path",
            "description": "Client id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ChooseBooksSource"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ClientBooksLink"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Choose which source a client’s engagements use",
        "tags": [
          "Integrations"
        ],
        "x-required-scopes": [
          "integrations:manage"
        ],
        "x-session-only": true
      }
    },
    "/api/v1/clients/{clientId}/books-link/invitation": {
      "post": {
        "description": "Sets Tolvi Books up from the client record (name, entity type, company number, year end) with the firm as its accountant under the firm’s engagement letter, invites the owner when an email is given, and links the client. Managers, partners and firm admins only.\n\nScopes: `integrations:manage`, `client_books:read`. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "ClientBooksLink_invite",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "clientId",
            "required": true,
            "in": "path",
            "description": "Client id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "A unique key (1-255 visible characters) to make retries safe. Replayed for 24 hours.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/InviteClientToBooks"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ClientBooksLink"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "A request with this Idempotency-Key is still being processed.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "422": {
            "description": "This Idempotency-Key was already used for a different request.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Invite a client’s business to Tolvi Books",
        "tags": [
          "Integrations"
        ],
        "x-required-scopes": [
          "integrations:manage",
          "client_books:read"
        ],
        "x-session-only": true
      }
    },
    "/api/v1/practice/books/clients": {
      "get": {
        "description": "Every business whose Tolvi Books the firm reaches (live and ended links), the client it is linked to, and for live links the books at a glance: entries posted, when last posted, receipts to review, VAT registration (bank lines to explain and VAT due appear once those are available).\n\nScopes: `client_books:read`.",
        "operationId": "PracticeClientsBooks_list",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ClientsBooksList"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "client_books:read"
            ]
          }
        ],
        "summary": "List clients’ books",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "client_books:read"
        ]
      }
    },
    "/api/v1/engagements/{id}/books/post-back/preview": {
      "post": {
        "description": "For an engagement approved at every stage whose trial balance came from the client’s Tolvi Books: the year-end adjustments the books would get (and any earlier post-back reversed because its journal changed), the books’ trial balance at the period end before and after, which must equal the final trial balance to the penny, and the year-end lock it would set. `problems` says what stands in the way. Nothing is posted. Session only; reviewers and above.\n\nScopes: `review:write`. Part of the `working_papers` product: the firm must have it and you must have access to it. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "PostBack_preview",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Engagement id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PostBackPreview"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Preview sending an engagement’s journals to the client’s Tolvi Books",
        "tags": [
          "Engagements"
        ],
        "x-required-scopes": [
          "review:write"
        ],
        "x-required-product": "working_papers",
        "x-session-only": true
      }
    },
    "/api/v1/engagements/{id}/books/post-back": {
      "post": {
        "description": "Posts the preview’s entries to the client’s books as year-end adjustments, through the firm’s practice link (year-end or full bookkeeping access), and locks the books to the period end, in one transaction. 409 with the reasons when the preview isn’t ready (not approved, the TB didn’t come from these books, missing accounts, the books wouldn’t agree, a lock). Safe to repeat: journals the books already hold are not posted again. Never creates a trial balance version. Session only; reviewers and above; not available through the MCP server.\n\nScopes: `review:write`. Part of the `working_papers` product: the firm must have it and you must have access to it. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "PostBack_post",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Engagement id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "A unique key (1-255 visible characters) to make retries safe. Replayed for 24 hours.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            }
          }
        ],
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PostBackResult"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "A request with this Idempotency-Key is still being processed.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "422": {
            "description": "This Idempotency-Key was already used for a different request.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Send an engagement’s journals to the client’s Tolvi Books and lock the year",
        "tags": [
          "Engagements"
        ],
        "x-required-scopes": [
          "review:write"
        ],
        "x-required-product": "working_papers",
        "x-session-only": true
      }
    },
    "/api/v1/clients/{clientId}/books-link/opening/preview": {
      "post": {
        "description": "Uses the client’s latest engagement approved at every stage, or the one named. Each final balance is placed on the books’ account by mapping, the same code on the same lead line, or the lead line’s default account; anything else is listed to map. `problems` says what stands in the way. Nothing is posted. Session only; reviewers and above.\n\nScopes: `review:write`. Part of the `working_papers` product: the firm must have it and you must have access to it. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "OpeningFromFinalTb_preview",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "clientId",
            "required": true,
            "in": "path",
            "description": "Client id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/StartBooksFromFinalTbInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StartBooksFromFinalTbPreview"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Preview starting a client’s books from its final trial balance",
        "tags": [
          "Clients"
        ],
        "x-required-scopes": [
          "review:write"
        ],
        "x-required-product": "working_papers",
        "x-session-only": true
      }
    },
    "/api/v1/clients/{clientId}/books-link/opening": {
      "post": {
        "description": "Posts the preview’s opening entry to the client’s books, dated the period end, through the firm’s practice link (year-end or full bookkeeping access). 409 with the reasons when the preview isn’t ready. Reversible from the books until the year is locked. Session only; reviewers and above; not available through the MCP server.\n\nScopes: `review:write`. Part of the `working_papers` product: the firm must have it and you must have access to it. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "OpeningFromFinalTb_post",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "clientId",
            "required": true,
            "in": "path",
            "description": "Client id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "A unique key (1-255 visible characters) to make retries safe. Replayed for 24 hours.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            }
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/StartBooksFromFinalTbInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StartBooksFromFinalTbResult"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "A request with this Idempotency-Key is still being processed.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "422": {
            "description": "This Idempotency-Key was already used for a different request.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Start a client’s books from its final trial balance",
        "tags": [
          "Clients"
        ],
        "x-required-scopes": [
          "review:write"
        ],
        "x-required-product": "working_papers",
        "x-session-only": true
      }
    },
    "/api/v1/books/accounts": {
      "get": {
        "description": "Every account, with its balance now and whether it has been used. Set up from the template for the business’s entity type when the business joined.\n\nScopes: `books:read`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "BooksAccounts_list",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BooksChartOfAccounts"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:read"
            ]
          }
        ],
        "summary": "Get the chart of accounts",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:read"
        ],
        "x-required-product": "books"
      },
      "post": {
        "description": "The business’s owners and admins (books:admin), or a linked practice whose access lets it post (year-end or full bookkeeping). Give a name and a category: Tolvi picks a free code and copies the mapping from a similar account.\n\nScopes: `books:write`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "BooksAccounts_create",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "A unique key (1-255 visible characters) to make retries safe. Replayed for 24 hours.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BooksCreateAccount"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BooksAccount"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "A request with this Idempotency-Key is still being processed.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "422": {
            "description": "This Idempotency-Key was already used for a different request.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:write"
            ]
          }
        ],
        "summary": "Add an account",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:write"
        ],
        "x-required-product": "books"
      }
    },
    "/api/v1/books/accounts/{accountId}": {
      "patch": {
        "description": "The business’s owners and admins (books:admin), or a linked practice whose access lets it post (year-end or full bookkeeping). Codes and classes never change.\n\nScopes: `books:write`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "BooksAccounts_update",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "accountId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BooksUpdateAccount"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BooksAccount"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:write"
            ]
          }
        ],
        "summary": "Rename or recategorise an account",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:write"
        ],
        "x-required-product": "books"
      },
      "delete": {
        "description": "The business’s owners and admins (books:admin), or a linked practice whose access lets it post (year-end or full bookkeeping). Only an account nothing has ever been posted to; once used, archive it instead (409).\n\nScopes: `books:write`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "BooksAccounts_remove",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "accountId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:write"
            ]
          }
        ],
        "summary": "Delete an unused account",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:write"
        ],
        "x-required-product": "books"
      }
    },
    "/api/v1/books/accounts/{accountId}/archive": {
      "post": {
        "description": "The business’s owners and admins (books:admin), or a linked practice whose access lets it post (year-end or full bookkeeping). Its history stays; it is no longer offered for new entries. Refused for accounts Tolvi keeps and for accounts with a balance.\n\nScopes: `books:write`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "BooksAccounts_archive",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "accountId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BooksAccount"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:write"
            ]
          }
        ],
        "summary": "Archive an account",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:write"
        ],
        "x-required-product": "books"
      }
    },
    "/api/v1/books/accounts/{accountId}/restore": {
      "post": {
        "description": "The business’s owners and admins (books:admin), or a linked practice whose access lets it post (year-end or full bookkeeping).\n\nScopes: `books:write`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "BooksAccounts_restore",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "accountId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BooksAccount"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:write"
            ]
          }
        ],
        "summary": "Restore an archived account",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:write"
        ],
        "x-required-product": "books"
      }
    },
    "/api/v1/books/accounts/{accountId}/ledger": {
      "get": {
        "description": "Postings between two dates with the balance brought forward and a running balance (debit positive).\n\nScopes: `books:read`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "BooksAccounts_ledger",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "accountId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "to",
            "required": false,
            "in": "query",
            "description": "Last day (inclusive). Defaults to today.",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "from",
            "required": false,
            "in": "query",
            "description": "First day (inclusive). Defaults to the start of the financial year containing `to`.",
            "schema": {
              "type": "string",
              "format": "date"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BooksAccountLedger"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:read"
            ]
          }
        ],
        "summary": "Get one account’s ledger",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:read"
        ],
        "x-required-product": "books"
      }
    },
    "/api/v1/books/entries": {
      "get": {
        "description": "Newest first, with their lines. Posted entries never change.\n\nScopes: `books:read`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "BooksEntries_list",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 50
            }
          },
          {
            "name": "beforeSeq",
            "required": false,
            "in": "query",
            "description": "The page before this entry number (from nextBeforeSeq).",
            "schema": {
              "type": "integer",
              "minimum": 1
            }
          },
          {
            "name": "accountId",
            "required": false,
            "in": "query",
            "description": "Only entries with a line on this account.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "kind",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "bank",
                "invoice",
                "credit_note",
                "bill",
                "bill_credit",
                "receipt",
                "expense_claim",
                "journal",
                "opening",
                "reversal",
                "year_end_adjustment",
                "vat_settlement",
                "fx_revaluation"
              ]
            }
          },
          {
            "name": "to",
            "required": false,
            "in": "query",
            "description": "Entries dated on or before.",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "from",
            "required": false,
            "in": "query",
            "description": "Entries dated on or after.",
            "schema": {
              "type": "string",
              "format": "date"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BooksEntryPage"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:read"
            ]
          }
        ],
        "summary": "List posted entries",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:read"
        ],
        "x-required-product": "books"
      }
    },
    "/api/v1/books/entries/{entryId}": {
      "get": {
        "operationId": "BooksEntries_get",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "entryId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BooksEntry"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:read"
            ]
          }
        ],
        "summary": "Get a posted entry",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:read"
        ],
        "x-required-product": "books",
        "description": "Scopes: `books:read`. Part of the `books` product: the firm must have it and you must have access to it."
      }
    },
    "/api/v1/books/entries/{entryId}/reverse": {
      "post": {
        "description": "Anyone who can write in the books (books:write), including a linked practice with year-end or full bookkeeping access; a read-only link can’t. For opening balances and adjustments posted without a journal: every line is negated, dated on the original’s date or the first open day after it. Void or amend a journal instead; change a bank line or invoice where it came from (409).\n\nScopes: `books:write`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "BooksEntries_reverse",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "entryId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "A unique key (1-255 visible characters) to make retries safe. Replayed for 24 hours.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            }
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BooksReverseEntry"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BooksEntry"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "A request with this Idempotency-Key is still being processed.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "422": {
            "description": "This Idempotency-Key was already used for a different request.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:write"
            ]
          }
        ],
        "summary": "Reverse an entry",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:write"
        ],
        "x-required-product": "books"
      }
    },
    "/api/v1/books/journals": {
      "get": {
        "description": "Newest first. Drafts carry the problems that stop them being posted.\n\nScopes: `books:read`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "BooksJournals_list",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "status",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "draft",
                "posted",
                "voided"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/BooksJournal"
                  }
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:read"
            ]
          }
        ],
        "summary": "List journals",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:read"
        ],
        "x-required-product": "books"
      },
      "post": {
        "description": "Anyone who can write in the books (books:write), including a linked practice with year-end or full bookkeeping access; a read-only link can’t. A draft touches nothing until it is posted.\n\nScopes: `books:write`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "BooksJournals_create",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "A unique key (1-255 visible characters) to make retries safe. Replayed for 24 hours.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BooksCreateJournal"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BooksJournal"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "A request with this Idempotency-Key is still being processed.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "422": {
            "description": "This Idempotency-Key was already used for a different request.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:write"
            ]
          }
        ],
        "summary": "Start a journal",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:write"
        ],
        "x-required-product": "books"
      }
    },
    "/api/v1/books/journals/{journalId}": {
      "get": {
        "operationId": "BooksJournals_get",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "journalId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BooksJournal"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:read"
            ]
          }
        ],
        "summary": "Get a journal",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:read"
        ],
        "x-required-product": "books",
        "description": "Scopes: `books:read`. Part of the `books` product: the firm must have it and you must have access to it."
      },
      "patch": {
        "description": "Anyone who can write in the books (books:write), including a linked practice with year-end or full bookkeeping access; a read-only link can’t. Posted journals are amended instead (409).\n\nScopes: `books:write`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "BooksJournals_update",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "journalId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BooksUpdateJournal"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BooksJournal"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:write"
            ]
          }
        ],
        "summary": "Change a draft journal",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:write"
        ],
        "x-required-product": "books"
      },
      "delete": {
        "description": "Anyone who can write in the books (books:write), including a linked practice with year-end or full bookkeeping access; a read-only link can’t. A posted journal is never deleted: void it (409).\n\nScopes: `books:write`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "BooksJournals_discard",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "journalId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:write"
            ]
          }
        ],
        "summary": "Discard a draft journal",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:write"
        ],
        "x-required-product": "books"
      }
    },
    "/api/v1/books/journals/{journalId}/post": {
      "post": {
        "description": "Anyone who can write in the books (books:write), including a linked practice with year-end or full bookkeeping access; a read-only link can’t. It must balance to the penny, use open accounts and be dated after any lock (422 lists every problem). VAT on lines is worked at the rate in force at the tax point and posted to the VAT account by Tolvi.\n\nScopes: `books:write`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "BooksJournals_post",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "journalId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BooksJournal"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:write"
            ]
          }
        ],
        "summary": "Post a journal",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:write"
        ],
        "x-required-product": "books"
      }
    },
    "/api/v1/books/journals/{journalId}/void": {
      "post": {
        "description": "Anyone who can write in the books (books:write), including a linked practice with year-end or full bookkeeping access; a read-only link can’t. Its entry is reversed, dated on the journal’s date or the first open day after it.\n\nScopes: `books:write`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "BooksJournals_void",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "journalId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BooksVoidJournal"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BooksJournal"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:write"
            ]
          }
        ],
        "summary": "Void a posted journal",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:write"
        ],
        "x-required-product": "books"
      }
    },
    "/api/v1/books/journals/{journalId}/amend": {
      "post": {
        "description": "Anyone who can write in the books (books:write), including a linked practice with year-end or full bookkeeping access; a read-only link can’t. Tolvi reverses the posted entry and posts the journal as sent, in one step. Either is dated in the first open period if its own date is locked.\n\nScopes: `books:write`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "BooksJournals_amend",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "journalId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BooksAmendJournal"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BooksJournal"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:write"
            ]
          }
        ],
        "summary": "Amend a posted journal",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:write"
        ],
        "x-required-product": "books"
      }
    },
    "/api/v1/books/trial-balance": {
      "get": {
        "description": "Derived from posted entries, never stored. Debit positive, credit negative.\n\nScopes: `books:read`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "BooksLedger_trialBalance",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "includeZero",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "true",
                "false"
              ]
            }
          },
          {
            "name": "throughSeq",
            "required": false,
            "in": "query",
            "description": "The ledger as it stood after this entry.",
            "schema": {
              "type": "integer",
              "minimum": 0
            }
          },
          {
            "name": "yearStart",
            "required": false,
            "in": "query",
            "description": "Defaults to the start of the financial year containing asAt, from the business’s year end.",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "asAt",
            "required": false,
            "in": "query",
            "description": "Defaults to today.",
            "schema": {
              "type": "string",
              "format": "date"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BooksTrialBalance"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:read"
            ]
          }
        ],
        "summary": "Get the trial balance at a date",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:read"
        ],
        "x-required-product": "books"
      }
    },
    "/api/v1/books/ledger/changes": {
      "get": {
        "description": "Postings made after `throughSeq` that change a balance on or before `asAt`.\n\nScopes: `books:read`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "BooksLedger_changes",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "asAt",
            "required": true,
            "in": "query",
            "description": "The period end it was taken for.",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "throughSeq",
            "required": true,
            "in": "query",
            "description": "The ledger point a trial balance was taken at.",
            "schema": {
              "type": "integer",
              "minimum": 0
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BooksLedgerChanges"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:read"
            ]
          }
        ],
        "summary": "List changes since a ledger point",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:read"
        ],
        "x-required-product": "books"
      }
    },
    "/api/v1/books/ledger/integrity": {
      "get": {
        "description": "Re-walks every entry from the first: numbered without gaps, each unchanged since it was posted, each balanced.\n\nScopes: `books:read`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "BooksLedger_integrity",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BooksLedgerIntegrity"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:read"
            ]
          }
        ],
        "summary": "Check the ledger’s hash chain",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:read"
        ],
        "x-required-product": "books"
      }
    },
    "/api/v1/books/locks": {
      "get": {
        "description": "The locks in force, their history and the first open date.\n\nScopes: `books:read`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "BooksLedger_getLocks",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "date",
            "required": false,
            "in": "query",
            "description": "A date to check: dateProblem says why it can’t take an entry. Defaults to today.",
            "schema": {
              "type": "string",
              "format": "date"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BooksLocks"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:read"
            ]
          }
        ],
        "summary": "Get the period locks",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:read"
        ],
        "x-required-product": "books"
      },
      "post": {
        "description": "Needs a signed-in person (never a token or connected app). The owner lock: the business’s owners and admins, or a linked practice that can post. The accountant’s year-end lock: only a linked practice, and only the practice that set it can reopen the year, with a reason. The VAT lock is set by Tolvi when HMRC accepts a return and can’t be changed here.\n\nScopes: `books:write`. Part of the `books` product: the firm must have it and you must have access to it. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "BooksLedger_changeLock",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BooksChangeLock"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BooksLocks"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Lock or unlock the books",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:write"
        ],
        "x-required-product": "books",
        "x-session-only": true
      }
    },
    "/api/v1/books/opening-balances": {
      "get": {
        "description": "The opening entry in force, if any, the suggested start date, and the accounts each plain-English question posts to.\n\nScopes: `books:read`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "BooksLedger_openingStatus",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BooksOpeningStatus"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:read"
            ]
          }
        ],
        "summary": "Get the opening balances in force",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:read"
        ],
        "x-required-product": "books"
      },
      "post": {
        "description": "The business’s owners and admins (books:admin), or a linked practice whose access lets it post (year-end or full bookkeeping). One entry dated the day before the books start. Every balance must have an account (422 lists any that don’t); a difference goes to suspense. Refused while earlier opening balances stand (409).\n\nScopes: `books:write`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "BooksLedger_postOpening",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "A unique key (1-255 visible characters) to make retries safe. Replayed for 24 hours.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BooksOpeningBalancesInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BooksOpeningBalancesPosted"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "A request with this Idempotency-Key is still being processed.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "422": {
            "description": "This Idempotency-Key was already used for a different request.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:write"
            ]
          }
        ],
        "summary": "Post opening balances",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:write"
        ],
        "x-required-product": "books"
      }
    },
    "/api/v1/books/opening-balances/preview": {
      "post": {
        "description": "The business’s owners and admins (books:admin), or a linked practice whose access lets it post (year-end or full bookkeeping). Where each balance would go and the entry that would be posted. Nothing is saved.\n\nScopes: `books:write`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "BooksLedger_previewOpening",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BooksOpeningBalancesInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BooksOpeningBalancesPreview"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:write"
            ]
          }
        ],
        "summary": "Preview opening balances",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:write"
        ],
        "x-required-product": "books"
      }
    },
    "/api/v1/books/receipts": {
      "get": {
        "description": "Newest first. Filter by the person’s decision: to_review, confirmed, discarded or all.\n\nScopes: `books:read`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "Receipts_list",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 100
            }
          },
          {
            "name": "review",
            "required": false,
            "in": "query",
            "schema": {
              "enum": [
                "to_review",
                "confirmed",
                "discarded",
                "all"
              ],
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReceiptList"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:read"
            ]
          }
        ],
        "summary": "List receipts",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:read"
        ],
        "x-required-product": "books"
      },
      "post": {
        "description": "Records a photo or file of a receipt (JPEG, PNG, WebP, HEIC or PDF, up to 20 MB) and returns a short-lived presigned URL to PUT it to storage with exactly the headers given; then call upload-complete. Send the app’s own `clientReference` for a capture so sending it again (an offline retry) returns the same receipt. Needs a person, not an API client.\n\nScopes: `books:write`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "Receipts_create",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "A unique key (1-255 visible characters) to make retries safe. Replayed for 24 hours.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateReceipt"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReceiptUpload"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "A request with this Idempotency-Key is still being processed.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "422": {
            "description": "This Idempotency-Key was already used for a different request.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:write"
            ]
          }
        ],
        "summary": "Add a receipt",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:write"
        ],
        "x-required-product": "books"
      }
    },
    "/api/v1/books/receipts/email-address": {
      "get": {
        "description": "Null until one is created.\n\nScopes: `books:read`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "Receipts_emailAddress",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReceiptEmailAddress"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:read"
            ]
          }
        ],
        "summary": "Get the address for emailing receipts in",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:read"
        ],
        "x-required-product": "books"
      },
      "post": {
        "description": "Anything emailed to it is read as a receipt for this business. Replacing it stops the old address working at once. The business’s owners and admins, signed in.\n\nScopes: `books:admin`. Part of the `books` product: the firm must have it and you must have access to it. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "Receipts_createEmailAddress",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReceiptEmailAddress"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Create or replace the address for emailing receipts in",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:admin"
        ],
        "x-required-product": "books",
        "x-session-only": true
      }
    },
    "/api/v1/books/receipts/{id}": {
      "get": {
        "description": "The file’s state, what Tolvi AI read (with how sure it is), the checks, possible bank payments and what was confirmed.\n\nScopes: `books:read`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "Receipts_get",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Receipt"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:read"
            ]
          }
        ],
        "summary": "Get a receipt",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:read"
        ],
        "x-required-product": "books"
      },
      "delete": {
        "description": "Removes a receipt that isn’t in the books, with its files. It can’t be undone. 409, saying why, when it has been confirmed, is in the books, is matched to a bank payment or is attached to a bill: those are accounting records. Signed in people only; recorded in the audit log.\n\nScopes: `books:write`. Part of the `books` product: the firm must have it and you must have access to it. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "Receipts_remove",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Deleted.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Delete a receipt for good",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:write"
        ],
        "x-required-product": "books",
        "x-session-only": true
      }
    },
    "/api/v1/books/receipts/{id}/image": {
      "get": {
        "description": "Only once the file has passed the virus check. Recorded in the audit log.\n\nScopes: `books:read`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "Receipts_image",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "variant",
            "required": false,
            "in": "query",
            "description": "preview (default): the JPEG made from a HEIC photo when there is one; original: the file as received.",
            "schema": {
              "enum": [
                "preview",
                "original"
              ],
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReceiptImage"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:read"
            ]
          }
        ],
        "summary": "Get a short-lived link to a receipt’s image",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:read"
        ],
        "x-required-product": "books"
      }
    },
    "/api/v1/books/receipts/{id}/upload": {
      "post": {
        "description": "A fresh PUT for a receipt still waiting for its file (the first PUT failed or expired). Only the person who added it; 409 once uploaded.\n\nScopes: `books:write`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "Receipts_presignAgain",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReceiptUpload"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:write"
            ]
          }
        ],
        "summary": "Presign a receipt upload again",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:write"
        ],
        "x-required-product": "books"
      }
    },
    "/api/v1/books/receipts/{id}/upload-complete": {
      "post": {
        "description": "Call after the PUT. Checks the stored file’s size, type and contents, records its checksum and starts the virus check. Once it passes, Tolvi AI reads it (readingStatus). 422 if the file is refused or malware is found.\n\nScopes: `books:write`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "Receipts_complete",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Receipt"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:write"
            ]
          }
        ],
        "summary": "Finish a receipt upload",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:write"
        ],
        "x-required-product": "books"
      }
    },
    "/api/v1/books/receipts/{id}/read-again": {
      "post": {
        "description": "After a reading failed. Only for receipts still to review.\n\nScopes: `books:write`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "Receipts_readAgain",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Receipt"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:write"
            ]
          }
        ],
        "summary": "Read a receipt again",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:write"
        ],
        "x-required-product": "books"
      }
    },
    "/api/v1/books/receipts/{id}/confirm": {
      "post": {
        "description": "The person’s figures (what Tolvi AI read, checked or corrected), optionally the bank payment it matches or that it was paid personally. Checks run again on these figures. Confirming records what it means for the books (postingProposal); the ledger posts it. Needs a person, not an API client.\n\nScopes: `books:write`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "Receipts_confirm",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ConfirmReceipt"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Receipt"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:write"
            ]
          }
        ],
        "summary": "Confirm a receipt",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:write"
        ],
        "x-required-product": "books"
      }
    },
    "/api/v1/books/receipts/{id}/discard": {
      "post": {
        "description": "Not a receipt, or a copy of one already added. The file is kept until the receipt is deleted. A confirmed receipt can’t be discarded.\n\nScopes: `books:write`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "Receipts_discard",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Receipt"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:write"
            ]
          }
        ],
        "summary": "Discard a receipt",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:write"
        ],
        "x-required-product": "books"
      }
    },
    "/api/v1/books/reports/profit-and-loss": {
      "get": {
        "description": "For any period, with a comparison period (by default the same dates a year earlier). Derived from posted entries. Every figure has a drillKey for the drill-down. Anyone who can read the books: the business’s own people (including view-only) and a linked practice.\n\nScopes: `books:read`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "BooksReports_profitAndLoss",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "compareTo",
            "required": false,
            "in": "query",
            "description": "An explicit comparison period (with compareFrom).",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "compareFrom",
            "required": false,
            "in": "query",
            "description": "An explicit comparison period (with compareTo).",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "compare",
            "required": false,
            "in": "query",
            "description": "previous_year (default), previous_period or none. Ignored when explicit comparison dates are given.",
            "schema": {
              "type": "string",
              "enum": [
                "previous_year",
                "previous_period",
                "none"
              ]
            }
          },
          {
            "name": "to",
            "required": false,
            "in": "query",
            "description": "Defaults to today.",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "from",
            "required": false,
            "in": "query",
            "description": "Defaults to the start of the financial year containing `to`.",
            "schema": {
              "type": "string",
              "format": "date"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BooksProfitAndLoss"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:read"
            ]
          }
        ],
        "summary": "Get the profit and loss",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:read"
        ],
        "x-required-product": "books"
      }
    },
    "/api/v1/books/reports/balance-sheet": {
      "get": {
        "description": "What the business owns and owes at a date, with a comparison date. Profit for the year so far is a line in capital and reserves. Anyone who can read the books: the business’s own people (including view-only) and a linked practice.\n\nScopes: `books:read`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "BooksReports_balanceSheet",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "compareAsAt",
            "required": false,
            "in": "query",
            "description": "An explicit comparison date.",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "compare",
            "required": false,
            "in": "query",
            "description": "previous_year (default: a year earlier), previous_period (the end of the previous financial year) or none.",
            "schema": {
              "type": "string",
              "enum": [
                "previous_year",
                "previous_period",
                "none"
              ]
            }
          },
          {
            "name": "asAt",
            "required": false,
            "in": "query",
            "description": "Defaults to today.",
            "schema": {
              "type": "string",
              "format": "date"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BooksBalanceSheet"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:read"
            ]
          }
        ],
        "summary": "Get the balance sheet",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:read"
        ],
        "x-required-product": "books"
      }
    },
    "/api/v1/books/reports/aged-debtors": {
      "get": {
        "description": "By customer and by how overdue. Anyone who can read the books: the business’s own people (including view-only) and a linked practice.\n\nScopes: `books:read`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "BooksReports_agedDebtors",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "asAt",
            "required": false,
            "in": "query",
            "description": "Defaults to today.",
            "schema": {
              "type": "string",
              "format": "date"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BooksAgedReport"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:read"
            ]
          }
        ],
        "summary": "Get aged debtors (who owes the business)",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:read"
        ],
        "x-required-product": "books"
      }
    },
    "/api/v1/books/reports/aged-creditors": {
      "get": {
        "description": "By supplier and by how overdue. Anyone who can read the books: the business’s own people (including view-only) and a linked practice.\n\nScopes: `books:read`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "BooksReports_agedCreditors",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "asAt",
            "required": false,
            "in": "query",
            "description": "Defaults to today.",
            "schema": {
              "type": "string",
              "format": "date"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BooksAgedReport"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:read"
            ]
          }
        ],
        "summary": "Get aged creditors (whom the business owes)",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:read"
        ],
        "x-required-product": "books"
      }
    },
    "/api/v1/books/reports/vat": {
      "get": {
        "description": "The VAT control account over a period, explained. The VAT return itself is worked separately from each transaction’s VAT. Anyone who can read the books: the business’s own people (including view-only) and a linked practice.\n\nScopes: `books:read`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "BooksReports_vat",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "to",
            "required": false,
            "in": "query",
            "description": "Defaults to today.",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "from",
            "required": false,
            "in": "query",
            "description": "Defaults to the start of the financial year containing `to`.",
            "schema": {
              "type": "string",
              "format": "date"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BooksVatOwed"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:read"
            ]
          }
        ],
        "summary": "Get the VAT owed per the books",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:read"
        ],
        "x-required-product": "books"
      }
    },
    "/api/v1/books/reports/cash-flow": {
      "get": {
        "description": "Money in and out of the bank, cash and card accounts, month by month, with the balance at each month end. Moving money between the business’s own accounts is neither. Up to five years. Anyone who can read the books: the business’s own people (including view-only) and a linked practice.\n\nScopes: `books:read`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "BooksReports_cashFlow",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "to",
            "required": false,
            "in": "query",
            "description": "Defaults to today.",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "from",
            "required": false,
            "in": "query",
            "description": "Defaults to the start of the financial year containing `to`.",
            "schema": {
              "type": "string",
              "format": "date"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BooksCashFlow"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:read"
            ]
          }
        ],
        "summary": "Get cash flow by month",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:read"
        ],
        "x-required-product": "books"
      }
    },
    "/api/v1/books/reports/sa103": {
      "get": {
        "description": "The income and expense boxes of HMRC’s SA103F (boxes 15 to 31 and 32 to 46, net profit or loss in 47 or 48), added up from each account’s SA103 line on the chart. An aid for the return, never a filing. The balance sheet boxes aren’t included. 422 unless the business is a sole trader. Anyone who can read the books: the business’s own people (including view-only) and a linked practice.\n\nScopes: `books:read`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "BooksReports_sa103",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "taxYear",
            "required": false,
            "in": "query",
            "description": "By the year it starts: 2026 is 2026/27. Defaults to the current tax year.",
            "schema": {
              "type": "integer",
              "minimum": 2024,
              "maximum": 2100
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BooksSa103Totals"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:read"
            ]
          }
        ],
        "summary": "Get SA103 totals (sole traders)",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:read"
        ],
        "x-required-product": "books"
      }
    },
    "/api/v1/books/reports/drill-down": {
      "get": {
        "description": "The postings that make up one figure, adding up to it. 422 for a figure that isn’t in the report. Anyone who can read the books: the business’s own people (including view-only) and a linked practice.\n\nScopes: `books:read`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "BooksReports_drillDown",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "asAt",
            "required": false,
            "in": "query",
            "description": "Balance sheet: the date (defaults to today); lines run from the year start.",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "to",
            "required": false,
            "in": "query",
            "description": "Profit and loss: the period end (defaults to today).",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "from",
            "required": false,
            "in": "query",
            "description": "Profit and loss: the period start (defaults to the year start).",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "key",
            "required": true,
            "in": "query",
            "description": "A figure’s drillKey, e.g. account:6100, section:overheads, category:premises, total:net_profit.",
            "schema": {
              "type": "string",
              "maxLength": 80
            }
          },
          {
            "name": "report",
            "required": true,
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "profit-and-loss",
                "balance-sheet"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BooksDrillDown"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:read"
            ]
          }
        ],
        "summary": "List the entries behind a report figure",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:read"
        ],
        "x-required-product": "books"
      }
    },
    "/api/v1/books/reports/tax-estimate": {
      "get": {
        "description": "Income tax and Class 4 National Insurance (sole traders) or corporation tax (companies) on the profit so far, annualised. Uses the extra information the owner saved for the tax year (other income, PAYE and pension contributions; a director’s salary and dividends), if any, and says which figures it used. Always an estimate, with its working and assumptions; never a figure for filing. 422 for a partnership or LLP, whose partners are taxed on their shares. Anyone who can read the books: the business’s own people (including view-only) and a linked practice.\n\nScopes: `books:read`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "BooksReports_taxEstimate",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "otherIncomePence",
            "required": false,
            "in": "query",
            "description": "Sole traders: other non-savings income for the year (a salary, say), in pence, assumed already taxed. When given, it is used instead of the extra information saved for the tax year (PUT /books/tax-details/{taxYear}).",
            "schema": {
              "type": "integer",
              "minimum": 0
            }
          },
          {
            "name": "asAt",
            "required": false,
            "in": "query",
            "description": "Defaults to today.",
            "schema": {
              "type": "string",
              "format": "date"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BooksTaxEstimate"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:read"
            ]
          }
        ],
        "summary": "Estimate the tax to set aside",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:read"
        ],
        "x-required-product": "books"
      }
    },
    "/api/v1/books/reports/{report}/export": {
      "get": {
        "description": "The same figures as the report (same query parameters), as a CSV (RFC 4180; amounts in pounds with two decimals, minus for negatives) or an A4 PDF (credits in brackets). Anyone who can read the books: the business’s own people (including view-only) and a linked practice.\n\nScopes: `books:read`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "BooksReports_export",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "report",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "enum": [
                "profit-and-loss",
                "balance-sheet",
                "aged-debtors",
                "aged-creditors",
                "vat",
                "drill-down",
                "cash-flow",
                "sa103"
              ]
            }
          },
          {
            "name": "drillReport",
            "required": false,
            "in": "query",
            "description": "drill-down only: profit-and-loss or balance-sheet.",
            "schema": {
              "type": "string",
              "enum": [
                "profit-and-loss",
                "balance-sheet"
              ]
            }
          },
          {
            "name": "key",
            "required": false,
            "in": "query",
            "description": "drill-down only: the figure’s drillKey.",
            "schema": {
              "type": "string",
              "maxLength": 80
            }
          },
          {
            "name": "taxYear",
            "required": false,
            "in": "query",
            "description": "sa103 only: the year the tax year starts.",
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "compareAsAt",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "compareTo",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "compareFrom",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "compare",
            "required": false,
            "in": "query",
            "description": "previous_year (default), previous_period or none. Ignored when explicit comparison dates are given.",
            "schema": {
              "type": "string",
              "enum": [
                "previous_year",
                "previous_period",
                "none"
              ]
            }
          },
          {
            "name": "asAt",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "to",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "from",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "format",
            "required": true,
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "csv",
                "pdf"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The file, as an attachment.",
            "content": {
              "text/csv": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              },
              "application/pdf": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:read"
            ]
          }
        ],
        "summary": "Download a report as CSV or PDF",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:read"
        ],
        "x-required-product": "books"
      }
    },
    "/api/v1/books/home": {
      "get": {
        "description": "How the business is doing (money in and out this month, profit so far this year, cash across accounts, who owes it and whom it owes, VAT owed), the tax to set aside (an estimate) and what needs the owner. Anyone who can read the books: the business’s own people (including view-only) and a linked practice.\n\nScopes: `books:read`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "BooksHome_home",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "asAt",
            "required": false,
            "in": "query",
            "description": "Defaults to today.",
            "schema": {
              "type": "string",
              "format": "date"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BooksHome"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:read"
            ]
          }
        ],
        "summary": "Get the home screen figures",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:read"
        ],
        "x-required-product": "books"
      }
    },
    "/api/v1/books/tax-details/{taxYear}": {
      "get": {
        "description": "What the owner entered for a more accurate tax to set aside, for one tax year; every figure is nil when nothing was entered. Anyone who can read the books: the business’s own people (including view-only) and a linked practice.\n\nScopes: `books:read`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "BooksTaxDetails_get",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "taxYear",
            "required": true,
            "in": "path",
            "description": "The tax year’s starting year (2026 = 2026/27). The tax estimate gives the year it uses as `extraInfoTaxYear`.",
            "schema": {
              "type": "integer",
              "minimum": 2000,
              "maximum": 2100
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BooksTaxDetails"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:read"
            ]
          }
        ],
        "summary": "Get the extra information for the tax estimate",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:read"
        ],
        "x-required-product": "books"
      },
      "put": {
        "description": "Replaces the figures for the tax year (anything left out is saved as nil). Only ever used for the estimate on Home; nothing is filed. The business’s people who can change the books, or an accountant whose link lets them (year_end or full_bookkeeping). View-only people and read-only links get 403.\n\nScopes: `books:write`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "BooksTaxDetails_put",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "taxYear",
            "required": true,
            "in": "path",
            "description": "The tax year’s starting year (2026 = 2026/27). The tax estimate gives the year it uses as `extraInfoTaxYear`.",
            "schema": {
              "type": "integer",
              "minimum": 2000,
              "maximum": 2100
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BooksTaxDetailsUpdate"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BooksTaxDetails"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:write"
            ]
          }
        ],
        "summary": "Save the extra information for the tax estimate",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:write"
        ],
        "x-required-product": "books"
      }
    },
    "/api/v1/books/bank/providers": {
      "get": {
        "description": "Whether open-banking connections are available to this business (and if not, why), and the banks to pick from when the provider doesn’t show its own picker. Statement files always work.\n\nScopes: `books:read`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "BooksBank_providers",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BooksBankProviderInfo"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:read"
            ]
          }
        ],
        "summary": "Can a bank be connected?",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:read"
        ],
        "x-required-product": "books"
      }
    },
    "/api/v1/books/bank/accounts": {
      "get": {
        "description": "Each account with its connection (and where it stands against the 90-day reconfirmation), its balance in the books, the bank’s balance, pending lines and how many lines are still to explain.\n\nScopes: `books:read`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "BooksBank_list",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BooksBankAccountList"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:read"
            ]
          }
        ],
        "summary": "List bank accounts",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:read"
        ],
        "x-required-product": "books"
      },
      "post": {
        "description": "For a bank without a feed: upload its statements. Tied to an account in the books (the one given, a free bank account, or a new one). The business’s owners and admins, or an accountant whose access can post.\n\nScopes: `books:write`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "BooksBank_create",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "A unique key (1-255 visible characters) to make retries safe. Replayed for 24 hours.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BooksBankCreateAccount"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BooksBankAccount"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "A request with this Idempotency-Key is still being processed.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "422": {
            "description": "This Idempotency-Key was already used for a different request.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:write"
            ]
          }
        ],
        "summary": "Add a bank account kept by statements",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:write"
        ],
        "x-required-product": "books"
      }
    },
    "/api/v1/books/bank/accounts/{id}": {
      "get": {
        "operationId": "BooksBank_get",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BooksBankAccount"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:read"
            ]
          }
        ],
        "summary": "Get a bank account",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:read"
        ],
        "x-required-product": "books",
        "description": "Scopes: `books:read`. Part of the `books` product: the firm must have it and you must have access to it."
      },
      "patch": {
        "description": "The statement balance and its date are what reconciliation checks the books against.\n\nScopes: `books:write`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "BooksBank_update",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BooksBankUpdateAccount"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BooksBankAccount"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:write"
            ]
          }
        ],
        "summary": "Rename a bank account or record its statement balance",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:write"
        ],
        "x-required-product": "books"
      }
    },
    "/api/v1/books/bank/accounts/{id}/reconciliation": {
      "get": {
        "description": "The statement (or bank) balance against the balance in the books, and what makes up the difference: lines not yet explained, entries in the books no bank line explains, and anything still to find.\n\nScopes: `books:read`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "BooksBank_reconciliation",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "asAt",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date"
            },
            "description": "Default: the latest statement balance’s date, else today with the bank’s balance."
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BooksBankReconciliation"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:read"
            ]
          }
        ],
        "summary": "Reconcile a bank account",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:read"
        ],
        "x-required-product": "books"
      }
    },
    "/api/v1/books/bank/accounts/{id}/imports/preview": {
      "post": {
        "description": "Reads the file without storing anything: its format, lines, what is new and the rows left out; or, for a CSV Tolvi doesn’t recognise, its headings to choose the columns from.\n\nScopes: `books:write`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "BooksBank_preview",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BooksBankStatementFile"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BooksBankStatementPreview"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:write"
            ]
          }
        ],
        "summary": "Preview a statement file",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:write"
        ],
        "x-required-product": "books"
      }
    },
    "/api/v1/books/bank/accounts/{id}/imports": {
      "post": {
        "description": "CSV, OFX/QFX, QIF or Santander’s text download. Lines already in the books (same id, or same date, amount, description and balance) are skipped, so overlapping files are safe. Tolvi then suggests what each new line is.\n\nScopes: `books:write`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "BooksBank_importFile",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "A unique key (1-255 visible characters) to make retries safe. Replayed for 24 hours.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BooksBankStatementFile"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BooksBankImport"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "A request with this Idempotency-Key is still being processed.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "422": {
            "description": "This Idempotency-Key was already used for a different request.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:write"
            ]
          }
        ],
        "summary": "Import a statement file",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:write"
        ],
        "x-required-product": "books"
      }
    },
    "/api/v1/books/bank/connections": {
      "post": {
        "description": "Returns the provider’s link: the person signs in at their bank there and is sent back to Tolvi Books (see callback). When providers.chooseBank is true (Yapily) bankId is required (422 without it). Read-only access, renewed every 90 days. Owners and admins, signed in. 503 when bank connections aren’t switched on.\n\nScopes: `books:admin`. Part of the `books` product: the firm must have it and you must have access to it. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "BooksBank_start",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BooksBankStartConnection"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BooksBankConnectStart"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Connect a bank",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:admin"
        ],
        "x-required-product": "books",
        "x-session-only": true
      }
    },
    "/api/v1/books/bank/connections/callback": {
      "post": {
        "description": "Send what the provider put on the redirect (state, and code or error). Returns the accounts the bank shared, to choose which to add.\n\nScopes: `books:admin`. Part of the `books` product: the firm must have it and you must have access to it. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "BooksBank_callback",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BooksBankConnectionCallback"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BooksBankConnectionAccounts"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Finish connecting a bank",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:admin"
        ],
        "x-required-product": "books",
        "x-session-only": true
      }
    },
    "/api/v1/books/bank/connections/{id}/accounts": {
      "get": {
        "description": "Each with whether it is already added and the account in the books Tolvi would use.\n\nScopes: `books:admin`. Part of the `books` product: the firm must have it and you must have access to it. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "BooksBank_connectionAccounts",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BooksBankConnectionAccounts"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "The accounts a bank shared",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:admin"
        ],
        "x-required-product": "books",
        "x-session-only": true
      },
      "post": {
        "description": "Each is tied to an account in the books (the one given, a free bank account, or a new one) and read straight away.\n\nScopes: `books:admin`. Part of the `books` product: the firm must have it and you must have access to it. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "BooksBank_addAccounts",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BooksBankAddAccounts"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BooksBankAccountList"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Add accounts from a connected bank",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:admin"
        ],
        "x-required-product": "books",
        "x-session-only": true
      }
    },
    "/api/v1/books/bank/connections/{id}/reconfirm": {
      "post": {
        "description": "The person’s explicit reconfirmation (FCA SCA-RTS Article 10A). When the bank wants them to sign in again, url says where to send them.\n\nScopes: `books:admin`. Part of the `books` product: the firm must have it and you must have access to it. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "BooksBank_reconfirm",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BooksBankReconfirm"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BooksBankReconfirmResult"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Keep sharing for another 90 days",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:admin"
        ],
        "x-required-product": "books",
        "x-session-only": true
      }
    },
    "/api/v1/books/bank/connections/{id}/disconnect": {
      "post": {
        "description": "Ends Tolvi’s access at the provider and forgets the tokens. The accounts and their lines stay; statements can still be uploaded.\n\nScopes: `books:admin`. Part of the `books` product: the firm must have it and you must have access to it. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "BooksBank_disconnect",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BooksBankConnection"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Disconnect a bank",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:admin"
        ],
        "x-required-product": "books",
        "x-session-only": true
      }
    },
    "/api/v1/books/bank/connections/{id}/sync": {
      "post": {
        "description": "Tolvi also reads each bank a few times a day.\n\nScopes: `books:write`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "BooksBank_sync",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BooksBankConnection"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:write"
            ]
          }
        ],
        "summary": "Read the bank now",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:write"
        ],
        "x-required-product": "books"
      }
    },
    "/api/v1/books/bank/lines": {
      "get": {
        "description": "Newest first, with Tolvi’s suggestion and its “Why?” for each line still to explain. Money in positive, money out negative.\n\nScopes: `books:read`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "BooksBankLines_list",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "q",
            "required": false,
            "in": "query",
            "description": "Search: words in the description, payee or reference, or an amount (12.50).",
            "schema": {
              "type": "string",
              "maxLength": 100
            }
          },
          {
            "name": "offset",
            "required": false,
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "default": 0
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 500,
              "default": 200
            }
          },
          {
            "name": "to",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "from",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "status",
            "required": false,
            "in": "query",
            "schema": {
              "enum": [
                "to_explain",
                "explained",
                "excluded",
                "all"
              ],
              "type": "string"
            }
          },
          {
            "name": "bankAccountId",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BooksBankLineList"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:read"
            ]
          }
        ],
        "summary": "List bank lines",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:read"
        ],
        "x-required-product": "books"
      }
    },
    "/api/v1/books/bank/lines/confirm": {
      "post": {
        "description": "Each line as suggested, or every line as one category. Each line posts on its own, so one that can’t be posted (a locked period, say) doesn’t stop the rest.\n\nScopes: `books:write`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "BooksBankLines_confirm",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BooksBankConfirmLines"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BooksBankConfirmResults"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:write"
            ]
          }
        ],
        "summary": "Confirm a group of lines",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:write"
        ],
        "x-required-product": "books"
      }
    },
    "/api/v1/books/bank/lines/{id}": {
      "get": {
        "operationId": "BooksBankLines_get",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BooksBankLine"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:read"
            ]
          }
        ],
        "summary": "Get a bank line",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:read"
        ],
        "x-required-product": "books",
        "description": "Scopes: `books:read`. Part of the `books` product: the firm must have it and you must have access to it."
      }
    },
    "/api/v1/books/bank/lines/{id}/explain": {
      "post": {
        "description": "As suggested; as a category (with VAT, or split); as a transfer to or from another of the business’s accounts; or as the payment for a confirmed receipt. Posts one entry in the books. 422 when it can’t be posted (a locked period, an unknown category), 409 when the line is already explained.\n\nScopes: `books:write`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "BooksBankLines_explain",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BooksBankExplainLine"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BooksBankLine"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:write"
            ]
          }
        ],
        "summary": "Explain a bank line",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:write"
        ],
        "x-required-product": "books"
      }
    },
    "/api/v1/books/bank/lines/{id}/undo": {
      "post": {
        "description": "Posts the reversal of its entry (dated in the first open period if the books are locked) and puts the line back to explain. A matched receipt goes back to waiting for its payment.\n\nScopes: `books:write`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "BooksBankLines_undo",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BooksBankLine"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:write"
            ]
          }
        ],
        "summary": "Undo a line’s explanation",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:write"
        ],
        "x-required-product": "books"
      }
    },
    "/api/v1/books/bank/lines/{id}/exclude": {
      "post": {
        "description": "A copy of another line, or nothing to do with the business: it stays in the list but never in the books.\n\nScopes: `books:write`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "BooksBankLines_exclude",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BooksBankLine"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:write"
            ]
          }
        ],
        "summary": "Set a line aside",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:write"
        ],
        "x-required-product": "books"
      }
    },
    "/api/v1/books/bank/lines/{id}/include": {
      "post": {
        "operationId": "BooksBankLines_include",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BooksBankLine"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:write"
            ]
          }
        ],
        "summary": "Bring back a line set aside",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:write"
        ],
        "x-required-product": "books",
        "description": "Scopes: `books:write`. Part of the `books` product: the firm must have it and you must have access to it."
      }
    },
    "/api/v1/books/bank/rules": {
      "get": {
        "description": "Each rule’s current version, as a sentence, with how many lines it has explained.\n\nScopes: `books:read`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "BooksBankRules_list",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/BooksBankRule"
                  }
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:read"
            ]
          }
        ],
        "summary": "List rules",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:read"
        ],
        "x-required-product": "books"
      },
      "post": {
        "description": "A rule needs a condition on the description, payee, reference or amount. postWithoutAsking: only the business’s owners and admins, signed in; even then a possible copy, a locked period, an unusual amount or a VAT-sensitive code is left for a person.\n\nScopes: `books:write`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "BooksBankRules_create",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "A unique key (1-255 visible characters) to make retries safe. Replayed for 24 hours.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BooksBankRuleInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BooksBankRule"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "A request with this Idempotency-Key is still being processed.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "422": {
            "description": "This Idempotency-Key was already used for a different request.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:write"
            ]
          }
        ],
        "summary": "Add a rule",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:write"
        ],
        "x-required-product": "books"
      }
    },
    "/api/v1/books/bank/rules/preview": {
      "post": {
        "description": "What it would catch among the lines already in the books, before saving it: “This rule would apply to 14 past lines (£512.40).”\n\nScopes: `books:read`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "BooksBankRules_preview",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BooksBankRuleInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BooksBankRulePreview"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:read"
            ]
          }
        ],
        "summary": "Preview a rule",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:read"
        ],
        "x-required-product": "books"
      }
    },
    "/api/v1/books/bank/rules/{id}": {
      "put": {
        "description": "Saves a new version; earlier versions are kept, so each entry still names the version that posted it.\n\nScopes: `books:write`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "BooksBankRules_update",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BooksBankRuleInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BooksBankRule"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:write"
            ]
          }
        ],
        "summary": "Change a rule",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:write"
        ],
        "x-required-product": "books"
      }
    },
    "/api/v1/books/bank/rules/{id}/remove": {
      "post": {
        "description": "It stops applying; lines it explained stay as they are (undo them one by one if needed).\n\nScopes: `books:write`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "BooksBankRules_remove",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:write"
            ]
          }
        ],
        "summary": "Remove a rule",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:write"
        ],
        "x-required-product": "books"
      }
    },
    "/api/v1/books/sales/summary": {
      "get": {
        "description": "What is owed and overdue as at today, by customer (most overdue first), with drafts and reminders waiting for the owner.\n\nScopes: `books:read`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "BooksSales_summary",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SalesSummary"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:read"
            ]
          }
        ],
        "summary": "Who owes the business money",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:read"
        ],
        "x-required-product": "books"
      }
    },
    "/api/v1/books/sales/settings": {
      "get": {
        "description": "Address, contact and bank details printed on invoices, the brand colour and logo, VAT rounding, terms, numbering and reminders.\n\nScopes: `books:read`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "BooksSales_getSettings",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SalesSettings"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:read"
            ]
          }
        ],
        "summary": "Get the invoice settings",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:read"
        ],
        "x-required-product": "books"
      },
      "patch": {
        "description": "The business’s owners and admins, or a practice whose link can post. The numbering prefixes can change only until something has been issued (409 after), so numbers always run in one sequence.\n\nScopes: `books:write`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "BooksSales_updateSettings",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SalesSettingsPatch"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SalesSettings"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:write"
            ]
          }
        ],
        "summary": "Change the invoice settings",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:write"
        ],
        "x-required-product": "books"
      }
    },
    "/api/v1/books/sales/settings/logo": {
      "post": {
        "description": "A PNG or JPEG up to 512 KB. PUT the image to the URL with exactly the headers given, then call logo/complete.\n\nScopes: `books:write`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "BooksSales_startLogo",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SalesLogoUploadRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SalesLogoUpload"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:write"
            ]
          }
        ],
        "summary": "Start uploading a logo",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:write"
        ],
        "x-required-product": "books"
      },
      "delete": {
        "operationId": "BooksSales_removeLogo",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SalesSettings"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:write"
            ]
          }
        ],
        "summary": "Take the logo off invoices",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:write"
        ],
        "x-required-product": "books",
        "description": "Scopes: `books:write`. Part of the `books` product: the firm must have it and you must have access to it."
      },
      "get": {
        "description": "Null when there is no logo, or it is still being checked.\n\nScopes: `books:read`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "BooksSales_logo",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SalesLogoLink"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:read"
            ]
          }
        ],
        "summary": "Get a short-lived link to the logo",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:read"
        ],
        "x-required-product": "books"
      }
    },
    "/api/v1/books/sales/settings/logo/complete": {
      "post": {
        "description": "Checks the stored image and scans it for viruses. It goes on invoices once it is clean (logoStatus available). 422 if it is refused.\n\nScopes: `books:write`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "BooksSales_completeLogo",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SalesSettings"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:write"
            ]
          }
        ],
        "summary": "Finish uploading a logo",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:write"
        ],
        "x-required-product": "books"
      }
    },
    "/api/v1/books/customers/{id}/statement": {
      "get": {
        "description": "Every issued invoice still owed at the date, with ageing that adds up to the total, and the email as it would go.\n\nScopes: `books:read`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "BooksStatements_get",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "asAt",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date"
            },
            "description": "Defaults to today."
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SalesStatement"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:read"
            ]
          }
        ],
        "summary": "Get a customer’s statement",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:read"
        ],
        "x-required-product": "books"
      }
    },
    "/api/v1/books/customers/{id}/statement/pdf": {
      "get": {
        "description": "As the customer receives it, with the business’s logo and colour.\n\nScopes: `books:read`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "BooksStatements_pdf",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "asAt",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date"
            },
            "description": "Defaults to today."
          }
        ],
        "responses": {
          "200": {
            "description": "The PDF",
            "content": {
              "application/pdf": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:read"
            ]
          }
        ],
        "summary": "Get a customer’s statement as a PDF",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:read"
        ],
        "x-required-product": "books"
      }
    },
    "/api/v1/books/customers/{id}/statement/send": {
      "post": {
        "description": "To the customer (or the address given), with the PDF attached, from Tolvi in the business’s name; replies go to the business. Only a person at the business, signed in: never an accountant in the books, an API client or an assistant. 409 if they owe nothing.\n\nScopes: `books:write`. Part of the `books` product: the firm must have it and you must have access to it. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "BooksStatements_send",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SalesStatementSendInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SalesStatement"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Email a customer their statement",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:write"
        ],
        "x-required-product": "books",
        "x-session-only": true
      }
    },
    "/api/v1/books/customers": {
      "get": {
        "description": "By name, with what each owes. `archived=true` lists archived customers instead.\n\nScopes: `books:read`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "BooksCustomers_list",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "archived",
            "required": false,
            "in": "query",
            "schema": {
              "enum": [
                "true",
                "false"
              ],
              "type": "string"
            }
          },
          {
            "name": "search",
            "required": false,
            "in": "query",
            "schema": {}
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CustomerList"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:read"
            ]
          }
        ],
        "summary": "List customers",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:read"
        ],
        "x-required-product": "books"
      },
      "post": {
        "description": "A UK VAT number must pass HMRC’s check digits (422 if not). Only HMRC can confirm a number is registered.\n\nScopes: `books:write`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "BooksCustomers_create",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "A unique key (1-255 visible characters) to make retries safe. Replayed for 24 hours.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CustomerInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Customer"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "A request with this Idempotency-Key is still being processed.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "422": {
            "description": "This Idempotency-Key was already used for a different request.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:write"
            ]
          }
        ],
        "summary": "Add a customer",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:write"
        ],
        "x-required-product": "books"
      }
    },
    "/api/v1/books/customers/{id}": {
      "get": {
        "operationId": "BooksCustomers_get",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Customer"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:read"
            ]
          }
        ],
        "summary": "Get a customer",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:read"
        ],
        "x-required-product": "books",
        "description": "Scopes: `books:read`. Part of the `books` product: the firm must have it and you must have access to it."
      },
      "patch": {
        "description": "Invoices already issued keep the details they were issued with.\n\nScopes: `books:write`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "BooksCustomers_update",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CustomerPatch"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Customer"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:write"
            ]
          }
        ],
        "summary": "Change a customer",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:write"
        ],
        "x-required-product": "books"
      }
    },
    "/api/v1/books/customers/{id}/archive": {
      "post": {
        "description": "Hidden from lists and new invoices. 409 while they still owe money.\n\nScopes: `books:write`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "BooksCustomers_archive",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Customer"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:write"
            ]
          }
        ],
        "summary": "Archive a customer",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:write"
        ],
        "x-required-product": "books"
      }
    },
    "/api/v1/books/customers/{id}/restore": {
      "post": {
        "operationId": "BooksCustomers_restore",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Customer"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:write"
            ]
          }
        ],
        "summary": "Restore an archived customer",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:write"
        ],
        "x-required-product": "books",
        "description": "Scopes: `books:write`. Part of the `books` product: the firm must have it and you must have access to it."
      }
    },
    "/api/v1/books/invoices": {
      "get": {
        "description": "Newest first. Status is worked out from payments and credit notes as at today.\n\nScopes: `books:read`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "BooksInvoices_list",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 500,
              "default": 200
            }
          },
          {
            "name": "customerId",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "status",
            "required": false,
            "in": "query",
            "schema": {
              "enum": [
                "all",
                "draft",
                "unpaid",
                "overdue",
                "paid",
                "void"
              ],
              "type": "string"
            }
          },
          {
            "name": "kind",
            "required": false,
            "in": "query",
            "schema": {
              "enum": [
                "invoice",
                "credit_note",
                "all"
              ],
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SalesDocumentList"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:read"
            ]
          }
        ],
        "summary": "List invoices or credit notes",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:read"
        ],
        "x-required-product": "books"
      },
      "post": {
        "description": "A draft posts nothing and can be changed or deleted. Pass the Tolvi AI suggestion’s id as aiSuggestionId when the draft came from a sentence; saving it records that the person accepted the suggestion.\n\nScopes: `books:write`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "BooksInvoices_create",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "A unique key (1-255 visible characters) to make retries safe. Replayed for 24 hours.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateSalesDocument"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SalesDocumentDetail"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "A request with this Idempotency-Key is still being processed.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "422": {
            "description": "This Idempotency-Key was already used for a different request.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:write"
            ]
          }
        ],
        "summary": "Start a draft invoice",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:write"
        ],
        "x-required-product": "books"
      }
    },
    "/api/v1/books/invoices/draft-from-sentence": {
      "post": {
        "description": "Tolvi AI reads a sentence such as \"Invoice Acme for 3 days’ consulting at £450 plus VAT\" and Tolvi builds a draft from your customers, VAT status and terms, with the questions to answer. A suggestion only: nothing is saved, issued or sent. Included in the Tolvi Books price. Needs a person; not available through MCP.\n\nScopes: `books:write`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "BooksInvoices_fromSentence",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DraftInvoiceFromSentence"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SalesDraftSuggestion"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:write"
            ]
          }
        ],
        "summary": "Draft an invoice from a sentence (Tolvi AI)",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:write"
        ],
        "x-required-product": "books"
      }
    },
    "/api/v1/books/invoices/{id}": {
      "get": {
        "description": "With its lines, totals, what is owed, payments, credit notes, emails sent and reminders. A draft lists what would stop it being issued.\n\nScopes: `books:read`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "BooksInvoices_get",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SalesDocumentDetail"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:read"
            ]
          }
        ],
        "summary": "Get an invoice or credit note",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:read"
        ],
        "x-required-product": "books"
      },
      "patch": {
        "description": "409 once issued: an issued invoice is corrected with a credit note.\n\nScopes: `books:write`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "BooksInvoices_update",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateSalesDocument"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SalesDocumentDetail"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:write"
            ]
          }
        ],
        "summary": "Change a draft",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:write"
        ],
        "x-required-product": "books"
      },
      "delete": {
        "description": "409 once issued: an issued invoice is never deleted, only cancelled with a credit note.\n\nScopes: `books:write`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "BooksInvoices_remove",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:write"
            ]
          }
        ],
        "summary": "Delete a draft",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:write"
        ],
        "x-required-product": "books"
      }
    },
    "/api/v1/books/invoices/{id}/duplicate": {
      "post": {
        "description": "A new draft for the same customer with the same lines and note, undated (it takes the date it is issued) and on the customer’s usual terms. The order number isn’t copied. Credit notes can’t be copied.\n\nScopes: `books:write`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "BooksInvoices_duplicate",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "A unique key (1-255 visible characters) to make retries safe. Replayed for 24 hours.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            }
          }
        ],
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SalesDocumentDetail"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "A request with this Idempotency-Key is still being processed.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "422": {
            "description": "This Idempotency-Key was already used for a different request.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:write"
            ]
          }
        ],
        "summary": "Copy an invoice as a new draft",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:write"
        ],
        "x-required-product": "books"
      }
    },
    "/api/v1/books/invoices/{id}/issue": {
      "post": {
        "description": "Takes the next number in the series (no gaps: VAT Regulations 1995 reg 14(1)(a)) and posts it to the books, in one step. 422 with every reason when it can’t be issued (for example a missing customer address on a VAT invoice, or a locked period); nothing is numbered or posted then.\n\nScopes: `books:write`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "BooksInvoices_issue",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/IssueSalesDocument"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SalesDocumentDetail"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:write"
            ]
          }
        ],
        "summary": "Issue an invoice or credit note",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:write"
        ],
        "x-required-product": "books"
      }
    },
    "/api/v1/books/invoices/{id}/credit-notes": {
      "post": {
        "description": "The whole invoice unless lines are given, at the VAT rates of the original supply (VAT Notice 700 section 19). Issue the credit note to post it.\n\nScopes: `books:write`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "BooksInvoices_creditNote",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "A unique key (1-255 visible characters) to make retries safe. Replayed for 24 hours.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreditNoteRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SalesDocumentDetail"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "A request with this Idempotency-Key is still being processed.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "422": {
            "description": "This Idempotency-Key was already used for a different request.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:write"
            ]
          }
        ],
        "summary": "Draft a credit note for an issued invoice",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:write"
        ],
        "x-required-product": "books"
      }
    },
    "/api/v1/books/invoices/{id}/void": {
      "post": {
        "description": "Issues a credit note for the whole invoice, so its number stays used and the books balance. 409 if anything has been paid or credited already (use a credit note instead).\n\nScopes: `books:write`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "BooksInvoices_voidInvoice",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "A unique key (1-255 visible characters) to make retries safe. Replayed for 24 hours.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/VoidInvoiceRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SalesDocumentDetail"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "A request with this Idempotency-Key is still being processed.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "422": {
            "description": "This Idempotency-Key was already used for a different request.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:write"
            ]
          }
        ],
        "summary": "Cancel an issued invoice",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:write"
        ],
        "x-required-product": "books"
      }
    },
    "/api/v1/books/invoices/{id}/payments": {
      "post": {
        "description": "Posts it to the books (into the bank or cash account given, out of money owed to you). No more than is still owed; not dated in the future.\n\nScopes: `books:write`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "BooksInvoices_pay",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "A unique key (1-255 visible characters) to make retries safe. Replayed for 24 hours.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RecordSalesPayment"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SalesDocumentDetail"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "A request with this Idempotency-Key is still being processed.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "422": {
            "description": "This Idempotency-Key was already used for a different request.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:write"
            ]
          }
        ],
        "summary": "Record a payment received",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:write"
        ],
        "x-required-product": "books"
      }
    },
    "/api/v1/books/invoices/{id}/pdf": {
      "get": {
        "description": "As the customer receives it, with the business’s logo and colour. A draft is marked DRAFT.\n\nScopes: `books:read`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "BooksInvoices_pdf",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The PDF",
            "content": {
              "application/pdf": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:read"
            ]
          }
        ],
        "summary": "Get the PDF",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:read"
        ],
        "x-required-product": "books"
      }
    },
    "/api/v1/books/invoices/{id}/send": {
      "post": {
        "description": "To the customer (or the address given), with the PDF attached, from Tolvi in the business’s name; replies go to the business. Only a person at the business, signed in: never an accountant in the books, an API client or an assistant.\n\nScopes: `books:write`. Part of the `books` product: the firm must have it and you must have access to it. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "BooksInvoices_send",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SendSalesDocument"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SalesDocumentDetail"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Email an issued invoice or credit note",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:write"
        ],
        "x-required-product": "books",
        "x-session-only": true
      }
    },
    "/api/v1/books/reminders": {
      "get": {
        "description": "Drafted by Tolvi for overdue (or nearly due) invoices; nothing is sent until a person at the business approves it.\n\nScopes: `books:read`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "BooksReminders_list",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "invoiceId",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "status",
            "required": false,
            "in": "query",
            "schema": {
              "enum": [
                "to_approve",
                "sent",
                "dismissed",
                "all"
              ],
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SalesReminderList"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:read"
            ]
          }
        ],
        "summary": "List payment reminders",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:read"
        ],
        "x-required-product": "books"
      }
    },
    "/api/v1/books/reminders/{id}": {
      "patch": {
        "description": "A person at the business, signed in.\n\nScopes: `books:write`. Part of the `books` product: the firm must have it and you must have access to it. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "BooksReminders_update",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateSalesReminder"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SalesReminder"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Edit a reminder before sending it",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:write"
        ],
        "x-required-product": "books",
        "x-session-only": true
      }
    },
    "/api/v1/books/reminders/{id}/send": {
      "post": {
        "description": "Emails it to the customer as it stands. Only a person at the business, signed in; 409 if the invoice has been paid.\n\nScopes: `books:write`. Part of the `books` product: the firm must have it and you must have access to it. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "BooksReminders_send",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SalesReminder"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Approve and send a reminder",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:write"
        ],
        "x-required-product": "books",
        "x-session-only": true
      }
    },
    "/api/v1/books/reminders/{id}/dismiss": {
      "post": {
        "description": "Not sent. The schedule moves on to the next step.\n\nScopes: `books:write`. Part of the `books` product: the firm must have it and you must have access to it. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "BooksReminders_dismiss",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SalesReminder"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Dismiss a reminder",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:write"
        ],
        "x-required-product": "books",
        "x-session-only": true
      }
    },
    "/api/v1/books/recurring-invoices": {
      "get": {
        "description": "By default those still running or paused. `invoiceId` finds the one an invoice was set up from, or made by.\n\nScopes: `books:read`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "BooksRecurringInvoices_list",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "customerId",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "invoiceId",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "status",
            "required": false,
            "in": "query",
            "schema": {
              "enum": [
                "current",
                "active",
                "paused",
                "stopped",
                "all"
              ],
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SalesRecurringInvoiceList"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:read"
            ]
          }
        ],
        "summary": "List repeating invoices",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:read"
        ],
        "x-required-product": "books"
      },
      "post": {
        "description": "Copies the invoice’s customer, lines, note and terms. On each date Tolvi makes a new draft for the owner to check: nothing is numbered, posted or sent. 409 if the invoice already repeats.\n\nScopes: `books:write`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "BooksRecurringInvoices_create",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "A unique key (1-255 visible characters) to make retries safe. Replayed for 24 hours.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SalesRecurringInvoiceInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SalesRecurringInvoice"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "A request with this Idempotency-Key is still being processed.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "422": {
            "description": "This Idempotency-Key was already used for a different request.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:write"
            ]
          }
        ],
        "summary": "Repeat an invoice",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:write"
        ],
        "x-required-product": "books"
      }
    },
    "/api/v1/books/recurring-invoices/{id}": {
      "get": {
        "operationId": "BooksRecurringInvoices_get",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SalesRecurringInvoice"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:read"
            ]
          }
        ],
        "summary": "Get a repeating invoice",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:read"
        ],
        "x-required-product": "books",
        "description": "Scopes: `books:read`. Part of the `books` product: the firm must have it and you must have access to it."
      },
      "patch": {
        "description": "How often, the next date (later dates follow from it), or what it bills, copied from another invoice for the same customer. Invoices already made don’t change.\n\nScopes: `books:write`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "BooksRecurringInvoices_update",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SalesRecurringInvoicePatch"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SalesRecurringInvoice"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:write"
            ]
          }
        ],
        "summary": "Change a repeating invoice",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:write"
        ],
        "x-required-product": "books"
      }
    },
    "/api/v1/books/recurring-invoices/{id}/auto-send": {
      "post": {
        "description": "On: each invoice is issued and emailed on its date, without anyone checking it, in the name of the person who turned this on. Only a person at the business, signed in: never an accountant in the books, an API client or an assistant. If anything is in the way the invoice stays a draft, and the schedule says why.\n\nScopes: `books:write`. Part of the `books` product: the firm must have it and you must have access to it. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "BooksRecurringInvoices_autoSend",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SalesRecurringAutoSend"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SalesRecurringInvoice"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Turn automatic sending on or off",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:write"
        ],
        "x-required-product": "books",
        "x-session-only": true
      }
    },
    "/api/v1/books/recurring-invoices/{id}/pause": {
      "post": {
        "description": "No more are made until it is resumed.\n\nScopes: `books:write`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "BooksRecurringInvoices_pause",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SalesRecurringInvoice"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:write"
            ]
          }
        ],
        "summary": "Pause a repeating invoice",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:write"
        ],
        "x-required-product": "books"
      }
    },
    "/api/v1/books/recurring-invoices/{id}/resume": {
      "post": {
        "description": "From its next date on or after today. Dates missed while it was paused aren’t billed.\n\nScopes: `books:write`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "BooksRecurringInvoices_resume",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SalesRecurringInvoice"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:write"
            ]
          }
        ],
        "summary": "Resume a paused repeating invoice",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:write"
        ],
        "x-required-product": "books"
      }
    },
    "/api/v1/books/recurring-invoices/{id}/stop": {
      "post": {
        "description": "For good. Invoices already made stay as they are.\n\nScopes: `books:write`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "BooksRecurringInvoices_stop",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SalesRecurringInvoice"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:write"
            ]
          }
        ],
        "summary": "Stop a repeating invoice",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:write"
        ],
        "x-required-product": "books"
      }
    },
    "/api/v1/books/vat/summary": {
      "get": {
        "description": "The next return and its deadline, what is owed (or due back) so far, the HMRC connection, whether filing from Tolvi is switched on, and anything that needs attention.\n\nScopes: `books:read`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "BooksVat_summary",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BooksVatSummary"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:read"
            ]
          }
        ],
        "summary": "Get VAT at a glance",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:read"
        ],
        "x-required-product": "books"
      }
    },
    "/api/v1/books/vat/settings": {
      "get": {
        "description": "The VAT number, return periods (stagger), registration date and the schemes over time, with the flat rate business types.\n\nScopes: `books:read`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "BooksVat_settings",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BooksVatSettings"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:read"
            ]
          }
        ],
        "summary": "Get the VAT settings",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:read"
        ],
        "x-required-product": "books"
      },
      "put": {
        "description": "The business’s owners and admins, signed in. The VAT number’s check digits are checked. A change of scheme (cash accounting, flat rate, annual accounting) starts a new stretch from `schemeFrom`; nothing a filed return covers can change.\n\nScopes: `books:admin`. Part of the `books` product: the firm must have it and you must have access to it. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "BooksVat_updateSettings",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BooksUpdateVatSettings"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BooksVatSettings"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Change the VAT settings",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:admin"
        ],
        "x-required-product": "books",
        "x-session-only": true
      }
    },
    "/api/v1/books/vat/obligations": {
      "get": {
        "description": "HMRC’s obligations as last fetched; before Tolvi is connected to HMRC, the periods expected from the return periods.\n\nScopes: `books:read`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "BooksVat_obligations",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BooksVatPeriods"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:read"
            ]
          }
        ],
        "summary": "List the VAT periods",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:read"
        ],
        "x-required-product": "books"
      }
    },
    "/api/v1/books/vat/returns/{periodKey}": {
      "get": {
        "description": "Worked out from the books now, with Tolvi’s own checks and the latest check before filing; once filed, the figures HMRC accepted and its receipt. `returnHash` identifies these exact figures.\n\nScopes: `books:read`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "BooksVat_return",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "periodKey",
            "required": true,
            "in": "path",
            "description": "HMRC’s period key (4 characters; `#` written as %23).",
            "schema": {
              "type": "string",
              "example": "26AC"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BooksVatReturn"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:read"
            ]
          }
        ],
        "summary": "Get a VAT return",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:read"
        ],
        "x-required-product": "books"
      }
    },
    "/api/v1/books/vat/returns/{periodKey}/lines": {
      "get": {
        "description": "Each line (or payment, under cash accounting) in the return and what it adds to each box, with why.\n\nScopes: `books:read`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "BooksVat_lines",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "periodKey",
            "required": true,
            "in": "path",
            "description": "HMRC’s period key (4 characters; `#` written as %23).",
            "schema": {
              "type": "string",
              "example": "26AC"
            }
          },
          {
            "name": "box",
            "required": false,
            "in": "query",
            "description": "Only the lines that add to this box (1 to 9). Box 3 shows boxes 1 and 2; box 5 shows 1, 2 and 4.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 9
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BooksVatReturnLines"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:read"
            ]
          }
        ],
        "summary": "List the lines behind a VAT return",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:read"
        ],
        "x-required-product": "books"
      }
    },
    "/api/v1/books/vat/returns/{periodKey}/check": {
      "post": {
        "description": "Tolvi’s own checks and Tolvi AI’s suggestions: unusual movements, purchases without receipts and reverse charge oddities. Suggestions only: nothing in the return or the books changes. Included in the Books price; not available through MCP.\n\nScopes: `books:write`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "BooksVat_check",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "periodKey",
            "required": true,
            "in": "path",
            "description": "HMRC’s period key (4 characters; `#` written as %23).",
            "schema": {
              "type": "string",
              "example": "26AC"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BooksVatCheck"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:write"
            ]
          }
        ],
        "summary": "Check a VAT return before filing",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:write"
        ],
        "x-required-product": "books"
      }
    },
    "/api/v1/books/vat/returns/{periodKey}/error-notification": {
      "post": {
        "description": "Corrections to earlier returns over the VAT Notice 700/45 limit can’t go on a return: the business tells HMRC separately (form VAT652), then records it here so they stay off every return. The business’s owners and admins, or an accountant through a full bookkeeping link (who accepts the agent’s declaration). Signed in only: never an API token, a connected app or MCP.\n\nScopes: `books:write`. Part of the `books` product: the firm must have it and you must have access to it. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "BooksVat_recordErrorNotification",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "periodKey",
            "required": true,
            "in": "path",
            "description": "HMRC’s period key (4 characters; `#` written as %23).",
            "schema": {
              "type": "string",
              "example": "26AC"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BooksVatRecordErrorNotification"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BooksVatReturn"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Record telling HMRC about corrections over the limit",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:write"
        ],
        "x-required-product": "books",
        "x-session-only": true
      }
    },
    "/api/v1/books/vat/returns/{periodKey}/submit": {
      "post": {
        "description": "The business’s owners and admins, or an accountant through a full bookkeeping link (who accepts the agent’s declaration). Signed in only: never an API token, a connected app or MCP. The person accepts HMRC’s declaration; `returnHash` must match the return they reviewed, or 409. A pending record is written before HMRC is called, so a lost answer is checked with HMRC rather than sent twice. When HMRC accepts, the period’s VAT lines lock. Answers 503 while filing from Tolvi is switched off (until HMRC approves Tolvi). Open even while Books is suspended.\n\nScopes: `books:write`. Part of the `books` product: the firm must have it and you must have access to it. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "BooksVat_submit",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "periodKey",
            "required": true,
            "in": "path",
            "description": "HMRC’s period key (4 characters; `#` written as %23).",
            "schema": {
              "type": "string",
              "example": "26AC"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "A unique key (1-255 visible characters) to make retries safe. Replayed for 24 hours.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BooksSubmitVatReturn"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BooksVatReturn"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "A request with this Idempotency-Key is still being processed.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "422": {
            "description": "This Idempotency-Key was already used for a different request.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "File a VAT return with HMRC",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:write"
        ],
        "x-required-product": "books",
        "x-session-only": true
      }
    },
    "/api/v1/books/vat/submissions": {
      "get": {
        "description": "Newest first, with HMRC’s receipts.\n\nScopes: `books:read`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "BooksVat_submissions",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BooksVatSubmissions"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:read"
            ]
          }
        ],
        "summary": "List VAT returns sent to HMRC",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:read"
        ],
        "x-required-product": "books"
      }
    },
    "/api/v1/books/vat/payments": {
      "get": {
        "description": "HMRC’s liabilities and payments for the last year, as last fetched.\n\nScopes: `books:read`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "BooksVat_payments",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BooksVatPaymentsAndLiabilities"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:read"
            ]
          }
        ],
        "summary": "Get VAT owed and paid at HMRC",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:read"
        ],
        "x-required-product": "books"
      }
    },
    "/api/v1/books/vat/hmrc": {
      "get": {
        "description": "Whether Tolvi may file for the business at HMRC, and when the authority ends (HMRC’s lasts 18 months).\n\nScopes: `books:read`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "BooksHmrc_connection",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BooksHmrcConnection"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:read"
            ]
          }
        ],
        "summary": "Get the HMRC connection",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:read"
        ],
        "x-required-product": "books"
      },
      "delete": {
        "description": "The business’s owners and admins, signed in. Tolvi forgets the tokens; filed returns stay.\n\nScopes: `books:admin`. Part of the `books` product: the firm must have it and you must have access to it. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "BooksHmrc_disconnect",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BooksHmrcConnection"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Disconnect from HMRC",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:admin"
        ],
        "x-required-product": "books",
        "x-session-only": true
      }
    },
    "/api/v1/books/vat/hmrc/authorize": {
      "post": {
        "description": "The business’s owners and admins, signed in. Returns HMRC’s sign-in URL; HMRC sends the person back to the Books app, which finishes with POST /books/vat/hmrc/callback. Never through MCP.\n\nScopes: `books:admin`. Part of the `books` product: the firm must have it and you must have access to it. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "BooksHmrc_authorize",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BooksHmrcAuthorize"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Start connecting to HMRC",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:admin"
        ],
        "x-required-product": "books",
        "x-session-only": true
      }
    },
    "/api/v1/books/vat/hmrc/callback": {
      "post": {
        "description": "Called by the Books app’s HMRC return page with the code and state, as the person who started. The state is single use and lasts 10 minutes. Tokens are encrypted and never returned.\n\nScopes: `books:admin`. Part of the `books` product: the firm must have it and you must have access to it. Only from a signed-in Tolvi session, never with an API token.",
        "operationId": "BooksHmrc_callback",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BooksHmrcCallback"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BooksHmrcConnection"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Finish connecting to HMRC",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:admin"
        ],
        "x-required-product": "books",
        "x-session-only": true
      }
    },
    "/api/v1/books/vat/hmrc/obligations/refresh": {
      "post": {
        "description": "Asks HMRC for the business’s obligations (about eight months back and four ahead) and keeps them. Send the browser’s facts for the fraud prevention headers.\n\nScopes: `books:write`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "BooksHmrc_refreshObligations",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BooksVatWithClientFacts"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BooksVatPeriods"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:write"
            ]
          }
        ],
        "summary": "Get the VAT periods from HMRC",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:write"
        ],
        "x-required-product": "books"
      }
    },
    "/api/v1/books/vat/hmrc/payments/refresh": {
      "post": {
        "description": "Asks HMRC for the business’s liabilities and payments over the last year and keeps them.\n\nScopes: `books:write`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "BooksHmrc_refreshPayments",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BooksVatWithClientFacts"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BooksVatPaymentsAndLiabilities"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:write"
            ]
          }
        ],
        "summary": "Get VAT owed and paid from HMRC",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:write"
        ],
        "x-required-product": "books"
      }
    },
    "/api/v1/books/inbox": {
      "get": {
        "description": "Bank lines still to explain, laid out as questions (Tolvi isn’t sure: two or three answers), suggested groups (one payee, one category: one tap confirms them all) and matches; “Do this every time?” rule offers; receipts to check, reminders to approve and invoices to chase; VAT returns due; and bank or HMRC connections running out. Says whether Tolvi AI is waiting for next month’s allowance (nothing is charged) and whether the viewer can act.\n\nScopes: `books:read`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "BooksInbox_get",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BooksInbox"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:read"
            ]
          }
        ],
        "summary": "Get the inbox",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:read"
        ],
        "x-required-product": "books"
      }
    },
    "/api/v1/books/inbox/confirm": {
      "post": {
        "description": "One line, a group or a selection: each as suggested, or all as one category (an answer to a question). Each line posts on its own, so one that can’t be posted doesn’t stop the rest. The business’s own people, or an accountant whose practice link lets them change the books (year_end or full_bookkeeping), as in Bank. A read-only link sees the inbox but gets 403 here.\n\nScopes: `books:write`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "BooksInbox_confirm",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BooksBankConfirmLines"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BooksBankConfirmResults"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:write"
            ]
          }
        ],
        "summary": "Confirm lines from the inbox",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:write"
        ],
        "x-required-product": "books"
      }
    },
    "/api/v1/books/inbox/undo": {
      "post": {
        "description": "Posts the reversal of each line’s entry and puts it back in the inbox. The business’s own people, or an accountant whose practice link lets them change the books (year_end or full_bookkeeping), as in Bank. A read-only link sees the inbox but gets 403 here.\n\nScopes: `books:write`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "BooksInbox_undo",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BooksInboxUndoLines"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BooksBankConfirmResults"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:write"
            ]
          }
        ],
        "summary": "Undo lines confirmed from the inbox",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:write"
        ],
        "x-required-product": "books"
      }
    },
    "/api/v1/books/inbox/lines/{id}/why": {
      "get": {
        "description": "Where the suggestion came from (your rule, your past choices, a match or Tolvi AI, with the model and prompt version), what this business chose before for the payee, and every decision on the line with who made it.\n\nScopes: `books:read`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "BooksInbox_why",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BooksInboxWhy"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:read"
            ]
          }
        ],
        "summary": "Why Tolvi suggested this",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:read"
        ],
        "x-required-product": "books"
      }
    },
    "/api/v1/books/inbox/activity": {
      "get": {
        "description": "The latest decisions on bank lines, newest first: confirmed, changed, answered, set aside, posted by a rule or undone, by whom (an accountant with their firm), and whether each can still be undone.\n\nScopes: `books:read`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "BooksInbox_activity",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BooksInboxActivity"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:read"
            ]
          }
        ],
        "summary": "Who confirmed what",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:read"
        ],
        "x-required-product": "books"
      }
    },
    "/api/v1/books/inbox/rule-offers/accept": {
      "post": {
        "description": "Saves the offered rule for the payee, so its lines are suggested that way from now on. It only suggests unless postWithoutAsking is set, which the business’s owners and admins can do signed in (403 otherwise). 404 when the offer no longer applies. The business’s own people, or an accountant whose practice link lets them change the books (year_end or full_bookkeeping), as in Bank. A read-only link sees the inbox but gets 403 here.\n\nScopes: `books:write`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "BooksInbox_accept",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BooksInboxAcceptRuleOffer"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BooksInboxRuleCreated"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:write"
            ]
          }
        ],
        "summary": "Accept a rule offer (“Yes, always”)",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:write"
        ],
        "x-required-product": "books"
      }
    },
    "/api/v1/books/inbox/rule-offers/decline": {
      "post": {
        "description": "“Not now” asks again after the next correction; “Ask me each time” stops offering for that payee. The business’s own people, or an accountant whose practice link lets them change the books (year_end or full_bookkeeping), as in Bank. A read-only link sees the inbox but gets 403 here.\n\nScopes: `books:write`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "BooksInbox_decline",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BooksInboxDeclineRuleOffer"
              }
            }
          }
        },
        "responses": {
          "204": {
            "description": "",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:write"
            ]
          }
        ],
        "summary": "Decline a rule offer",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:write"
        ],
        "x-required-product": "books"
      }
    },
    "/api/v1/books/purchases/summary": {
      "get": {
        "description": "What is owed, overdue and due in the next 7 days as at today, by supplier (most overdue first), with drafts.\n\nScopes: `books:read`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "BooksPurchases_summary",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BooksPurchasesSummary"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:read"
            ]
          }
        ],
        "summary": "What the business owes",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:read"
        ],
        "x-required-product": "books"
      }
    },
    "/api/v1/books/suppliers": {
      "get": {
        "description": "By name, with what is still owed to each.\n\nScopes: `books:read`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "BooksSuppliers_list",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "q",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "archived",
            "required": false,
            "in": "query",
            "schema": {
              "enum": [
                "live",
                "archived",
                "all"
              ],
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BooksSupplierList"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:read"
            ]
          }
        ],
        "summary": "List suppliers",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:read"
        ],
        "x-required-product": "books"
      },
      "post": {
        "operationId": "BooksSuppliers_create",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "A unique key (1-255 visible characters) to make retries safe. Replayed for 24 hours.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BooksSupplierInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BooksSupplier"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "A request with this Idempotency-Key is still being processed.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "422": {
            "description": "This Idempotency-Key was already used for a different request.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:write"
            ]
          }
        ],
        "summary": "Add a supplier",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:write"
        ],
        "x-required-product": "books",
        "description": "Scopes: `books:write`. Part of the `books` product: the firm must have it and you must have access to it."
      }
    },
    "/api/v1/books/suppliers/{id}": {
      "get": {
        "operationId": "BooksSuppliers_get",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BooksSupplier"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:read"
            ]
          }
        ],
        "summary": "Get a supplier",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:read"
        ],
        "x-required-product": "books",
        "description": "Scopes: `books:read`. Part of the `books` product: the firm must have it and you must have access to it."
      },
      "patch": {
        "description": "A supplier who is still owed money can’t be archived. Posted bills keep the name they were posted with.\n\nScopes: `books:write`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "BooksSuppliers_update",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BooksSupplierPatch"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BooksSupplier"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:write"
            ]
          }
        ],
        "summary": "Change or archive a supplier",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:write"
        ],
        "x-required-product": "books"
      }
    },
    "/api/v1/books/bills": {
      "get": {
        "description": "Newest first. Status is worked out as at today: to_pay includes part-paid bills; overdue is past its due date with something still to pay.\n\nScopes: `books:read`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "BooksBills_list",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "supplierId",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "kind",
            "required": false,
            "in": "query",
            "schema": {
              "enum": [
                "bill",
                "supplier_credit",
                "all"
              ],
              "type": "string"
            }
          },
          {
            "name": "status",
            "required": false,
            "in": "query",
            "schema": {
              "enum": [
                "all",
                "draft",
                "to_pay",
                "overdue",
                "paid",
                "void"
              ],
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BooksBillList"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:read"
            ]
          }
        ],
        "summary": "List bills",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:read"
        ],
        "x-required-product": "books"
      },
      "post": {
        "description": "Give a supplierId, or a supplierName to find or add one. With `post: true` it goes into the books straight away (Dr costs and VAT, Cr creditors); otherwise it stays a draft. With a receiptId the photo or PDF stays with the bill; posting confirms the receipt with these figures, which is the person’s decision on what Tolvi AI read. 409 if the same supplier reference has already been added.\n\nScopes: `books:write`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "BooksBills_create",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "A unique key (1-255 visible characters) to make retries safe. Replayed for 24 hours.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BooksCreateBill"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BooksBillDetail"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "A request with this Idempotency-Key is still being processed.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "422": {
            "description": "This Idempotency-Key was already used for a different request.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:write"
            ]
          }
        ],
        "summary": "Start or add a bill",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:write"
        ],
        "x-required-product": "books"
      }
    },
    "/api/v1/books/bills/from-receipt/{receiptId}": {
      "get": {
        "description": "A suggestion to check, from a receipt or bill that has been read. Nothing is saved or posted.\n\nScopes: `books:read`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "BooksBills_fromReceipt",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "receiptId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BooksBillProposal"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:read"
            ]
          }
        ],
        "summary": "A bill as Tolvi AI read it",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:read"
        ],
        "x-required-product": "books"
      }
    },
    "/api/v1/books/bills/{id}": {
      "get": {
        "description": "With its lines, what is owed, payments and credits.\n\nScopes: `books:read`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "BooksBills_get",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BooksBillDetail"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:read"
            ]
          }
        ],
        "summary": "Get a bill",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:read"
        ],
        "x-required-product": "books"
      },
      "patch": {
        "description": "409 once it is in the books: a posted bill is corrected with a credit.\n\nScopes: `books:write`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "BooksBills_update",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BooksUpdateBill"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BooksBillDetail"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:write"
            ]
          }
        ],
        "summary": "Change a draft bill",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:write"
        ],
        "x-required-product": "books"
      },
      "delete": {
        "description": "409 once it is in the books. The file it came from is kept.\n\nScopes: `books:write`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "BooksBills_remove",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:write"
            ]
          }
        ],
        "summary": "Delete a draft bill",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:write"
        ],
        "x-required-product": "books"
      }
    },
    "/api/v1/books/bills/{id}/post": {
      "post": {
        "description": "Posts it through the ledger with VAT on every line, in one step. 422 with the reasons when it can’t post (for example a locked period).\n\nScopes: `books:write`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "BooksBills_post",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BooksBillDetail"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:write"
            ]
          }
        ],
        "summary": "Add a draft bill to the books",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:write"
        ],
        "x-required-product": "books"
      }
    },
    "/api/v1/books/bills/{id}/credit": {
      "post": {
        "description": "All of what hasn’t been credited, or amountPence gross shared across the bill’s lines, at the VAT rates of the original supply (VAT Notice 700 section 19). Posts straight away.\n\nScopes: `books:write`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "BooksBills_credit",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "A unique key (1-255 visible characters) to make retries safe. Replayed for 24 hours.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BooksCreditBill"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BooksBillDetail"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "A request with this Idempotency-Key is still being processed.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "422": {
            "description": "This Idempotency-Key was already used for a different request.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:write"
            ]
          }
        ],
        "summary": "Record a supplier credit note",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:write"
        ],
        "x-required-product": "books"
      }
    },
    "/api/v1/books/bills/{id}/void": {
      "post": {
        "description": "Posts a credit for the whole bill, so the record stays and the books balance. 409 if anything has been paid or credited.\n\nScopes: `books:write`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "BooksBills_voidBill",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "A unique key (1-255 visible characters) to make retries safe. Replayed for 24 hours.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BooksVoidBill"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BooksBillDetail"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "A request with this Idempotency-Key is still being processed.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "422": {
            "description": "This Idempotency-Key was already used for a different request.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:write"
            ]
          }
        ],
        "summary": "Cancel a bill",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:write"
        ],
        "x-required-product": "books"
      }
    },
    "/api/v1/books/bills/{id}/payments": {
      "post": {
        "description": "For money paid outside the bank feed. Part payments are fine; no more than is owed. Dr creditors, Cr the account it came from, and the share of the bill’s VAT settled for cash accounting. Tolvi doesn’t send the money. A bank line is matched in Bank instead.\n\nScopes: `books:write`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "BooksBills_pay",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "A unique key (1-255 visible characters) to make retries safe. Replayed for 24 hours.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BooksPayBill"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BooksBillDetail"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "A request with this Idempotency-Key is still being processed.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "422": {
            "description": "This Idempotency-Key was already used for a different request.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:write"
            ]
          }
        ],
        "summary": "Record a payment made",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:write"
        ],
        "x-required-product": "books"
      }
    },
    "/api/v1/books/bills/{id}/payments/{paymentId}/undo": {
      "post": {
        "description": "Posts the reversal and reverses its VAT settlement. 409 for one matched from a bank line: undo that in Bank.\n\nScopes: `books:write`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "BooksBills_undo",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "paymentId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BooksBillDetail"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found in this firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:write"
            ]
          }
        ],
        "summary": "Undo a payment recorded by hand",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:write"
        ],
        "x-required-product": "books"
      }
    },
    "/api/v1/books/getting-started": {
      "get": {
        "description": "Six steps for a new business, each ticked from real data: business details, a bank, starting balances, how invoices look, VAT and an accountant.\n\nScopes: `books:read`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "BooksGettingStarted_read",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BooksGettingStarted"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:read"
            ]
          }
        ],
        "summary": "Get the getting-started checklist",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:read"
        ],
        "x-required-product": "books"
      },
      "put": {
        "description": "Hide the list or bring it back, and the two answers only a person can give: not registered for VAT, and nothing to bring forward. The business’s owners and admins, or a practice with a link that can post.\n\nScopes: `books:write`. Part of the `books` product: the firm must have it and you must have access to it.",
        "operationId": "BooksGettingStarted_update",
        "parameters": [
          {
            "name": "x-firm-id",
            "in": "header",
            "description": "The firm to act in, if you belong to several. Must be one of your own firms.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BooksUpdateGettingStarted"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BooksGettingStarted"
                }
              }
            },
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential. The WWW-Authenticate header points to the protected-resource metadata.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Not allowed: missing role or scope (WWW-Authenticate says which scope), or another firm.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          },
          {
            "oauth2": [
              "books:write"
            ]
          }
        ],
        "summary": "Answer or hide the getting-started checklist",
        "tags": [
          "Books"
        ],
        "x-required-scopes": [
          "books:write"
        ],
        "x-required-product": "books"
      }
    }
  },
  "info": {
    "title": "Tolvi API",
    "description": "The Tolvi public API. The web app and the MCP server use exactly this API.\n\n**Authentication.** Send `Authorization: Bearer <token>` with one of:\n- an OIDC access token from Tolvi sign-in (OAuth 2.1 authorization code + PKCE, for apps and MCP clients acting for a user),\n- a personal access token (`twp_…`), limited to its scopes and its owner's current role,\n- a client-credentials access token (`twat_…`) from `POST /api/v1/oauth/token`.\n\nEffective permission is the caller's role ∩ the token's scopes. If you belong to several firms, choose one with `x-firm-id`.\n\n**Errors** are RFC 9457 problem details (`application/problem+json`).\n\n**Pagination** is cursor-based: pass `limit` (1-100) and the previous page's `nextCursor` as `cursor`. Lists return `{ rows, nextCursor, pageSize }`.\n\n**Idempotency.** POSTs marked with an `Idempotency-Key` parameter can be retried safely: the first successful response is replayed for 24 hours (with `Idempotent-Replayed: true`). Reusing a key for a different request is a 422.\n\n**Rate limits** apply to each API credential or connected app by plan, to each person signed in to the web app with a higher cap for their whole firm, and per IP address before sign-in. Every response carries `RateLimit-*` headers; a 429 has `Retry-After`, and its `rateLimitScope` says which limit was hit.\n\n**Versioning.** Paths start `/api/v1`. Changes within v1 are additive; removals get deprecation headers and six months' notice.",
    "version": "1.0.0",
    "contact": {}
  },
  "tags": [],
  "servers": [
    {
      "url": "https://api.tolvi.co.uk",
      "description": "Production"
    },
    {
      "url": "http://localhost:3000",
      "description": "Local development"
    }
  ],
  "components": {
    "securitySchemes": {
      "bearer": {
        "scheme": "bearer",
        "bearerFormat": "JWT",
        "type": "http",
        "description": "OIDC access token, personal access token (twp_…) or client-credentials access token (twat_…)."
      },
      "oauth2": {
        "type": "oauth2",
        "flows": {
          "clientCredentials": {
            "tokenUrl": "/api/v1/oauth/token",
            "scopes": {
              "work:read": "Read the work queue",
              "clients:read": "Read clients",
              "clients:write": "Create and edit clients",
              "engagements:read": "Read year-end files and working papers",
              "engagements:write": "Prepare working papers, sign sections off and assign work",
              "review:write": "Raise, clear and reopen review points; approve, return and reopen year-end files",
              "integrations:manage": "Connect and disconnect clients’ bookkeeping software",
              "settings:read": "Read firm settings and the team (names, emails, roles and capacity)",
              "settings:admin": "Change everyday firm settings and see invitations (security, firm details, workflows, AI and people need a signed-in person)",
              "webhooks:manage": "Manage webhook subscriptions and see their deliveries",
              "meetings:read": "Read meetings: transcripts and their write-ups (summary, takeaways, next steps, open questions, draft follow-up email)",
              "meetings:write": "Send note-takers to meetings and file them against clients",
              "client_books:read": "See which businesses have linked their Tolvi Books to the firm, and the state of each link",
              "books:read": "Read a business’s books in Tolvi Books (as the business, or as its linked accountant)",
              "books:write": "Keep a business’s books: categorise, reconcile, invoices, receipts and journals (an accountant also needs the link’s access)",
              "books:admin": "Change a business’s Tolvi Books set-up: its details, rules that post without asking, connections and who has access (some of it needs a signed-in person)",
              "self_assessment:read": "Read clients’ self assessment returns and calculations, without their National Insurance numbers or dates of birth",
              "self_assessment:write": "Prepare clients’ self assessment returns. Approving and filing stay with signed-in people",
              "accounts:read": "Read clients’ statutory year end accounts: figures, notes and PDFs",
              "accounts:write": "Prepare clients’ statutory year end accounts. Approving them stays with signed-in people",
              "corporation_tax:read": "Read clients’ Company Tax Returns: boxes, computations and PDFs",
              "corporation_tax:write": "Prepare clients’ Company Tax Returns. Approving and filing them stay with signed-in people"
            }
          }
        },
        "description": "Client credentials for server-to-server integrations. Apps acting for a user use authorization code + PKCE with the identity provider in /.well-known/oauth-protected-resource."
      }
    },
    "schemas": {
      "ImportKind": {
        "type": "string",
        "enum": [
          "clients",
          "trial_balance",
          "ct_opening",
          "sa_prior_year"
        ]
      },
      "ImportStatus": {
        "type": "string",
        "enum": [
          "pending_upload",
          "pending_scan",
          "reading",
          "needs_mapping",
          "checking",
          "ready",
          "importing",
          "completed",
          "undoing",
          "undone",
          "failed",
          "rejected"
        ]
      },
      "ImportColumnConfidence": {
        "type": "string",
        "enum": [
          "exact",
          "close",
          "none"
        ]
      },
      "ImportColumn": {
        "type": "object",
        "properties": {
          "column": {
            "type": "integer"
          },
          "header": {
            "type": "string"
          },
          "field": {
            "type": [
              "string",
              "null"
            ],
            "description": "The field it goes to, or null to ignore it."
          },
          "confidence": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ImportColumnConfidence"
              }
            ]
          },
          "refused": {
            "type": "string",
            "description": "Set when Tolvi won’t keep this column, with what it holds."
          },
          "samples": {
            "description": "The first few values.",
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        },
        "description": "One column of the file, with what Tolvi thinks it is.",
        "required": [
          "column",
          "header",
          "field",
          "confidence",
          "samples"
        ]
      },
      "ImportTbUse": {
        "type": "string",
        "enum": [
          "this_year",
          "comparatives"
        ]
      },
      "ImportCounts": {
        "type": "object",
        "properties": {
          "ready": {
            "type": "integer"
          },
          "warning": {
            "type": "integer"
          },
          "error": {
            "type": "integer"
          },
          "duplicate": {
            "type": "integer"
          },
          "toImport": {
            "type": "integer",
            "description": "Rows a person has chosen to bring in."
          },
          "created": {
            "type": "integer"
          },
          "updated": {
            "type": "integer"
          },
          "applied": {
            "type": "integer"
          },
          "skipped": {
            "type": "integer"
          },
          "failed": {
            "type": "integer"
          },
          "undone": {
            "type": "integer"
          },
          "kept": {
            "type": "integer",
            "description": "Left in place by undo, with the reason on the row."
          }
        },
        "required": [
          "ready",
          "warning",
          "error",
          "duplicate",
          "toImport",
          "created",
          "updated",
          "applied",
          "skipped",
          "failed",
          "undone",
          "kept"
        ]
      },
      "ImportBatch": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "kind": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ImportKind"
              }
            ]
          },
          "status": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ImportStatus"
              }
            ]
          },
          "fileName": {
            "type": "string"
          },
          "sizeBytes": {
            "type": "integer"
          },
          "problem": {
            "type": [
              "string",
              "null"
            ],
            "description": "Why it stopped, in plain words."
          },
          "notices": {
            "description": "About the file as a whole, such as columns left out.",
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "sheets": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "sheet": {
            "type": [
              "string",
              "null"
            ]
          },
          "headerLine": {
            "type": [
              "integer",
              "null"
            ],
            "description": "The line or row the headings were found on."
          },
          "columns": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ImportColumn"
            }
          },
          "clientId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid",
            "description": "Trial balance: whose."
          },
          "clientName": {
            "type": [
              "string",
              "null"
            ]
          },
          "periodEnd": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31"
          },
          "use": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/ImportTbUse"
              },
              {
                "type": "null"
              }
            ]
          },
          "totalRows": {
            "type": "integer"
          },
          "skippedRows": {
            "type": "integer",
            "description": "Blank, total and heading rows left out when reading."
          },
          "doneRows": {
            "type": "integer"
          },
          "counts": {
            "$ref": "#/components/schemas/ImportCounts"
          },
          "createdByName": {
            "type": [
              "string",
              "null"
            ]
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "confirmedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "completedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "undoneAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          }
        },
        "description": "One uploaded file on its way into Tolvi.",
        "required": [
          "id",
          "kind",
          "status",
          "fileName",
          "sizeBytes",
          "problem",
          "notices",
          "sheets",
          "sheet",
          "headerLine",
          "columns",
          "clientId",
          "clientName",
          "periodEnd",
          "use",
          "totalRows",
          "skippedRows",
          "doneRows",
          "counts",
          "createdByName",
          "createdAt",
          "confirmedAt",
          "completedAt",
          "undoneAt"
        ]
      },
      "ImportBatchList": {
        "type": "object",
        "properties": {
          "batches": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ImportBatch"
            }
          }
        },
        "required": [
          "batches"
        ]
      },
      "ImportField": {
        "type": "object",
        "properties": {
          "key": {
            "type": "string",
            "example": "companyNumber"
          },
          "label": {
            "type": "string",
            "example": "Company number"
          },
          "required": {
            "type": "boolean"
          },
          "multiple": {
            "type": "boolean",
            "description": "Several columns may feed it."
          }
        },
        "description": "Somewhere a column can go.",
        "required": [
          "key",
          "label",
          "required",
          "multiple"
        ]
      },
      "ImportKindInfo": {
        "type": "object",
        "properties": {
          "kind": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ImportKind"
              }
            ]
          },
          "label": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "available": {
            "type": "boolean",
            "description": "False when this firm or person can’t use the product it goes into."
          },
          "unavailableReason": {
            "type": [
              "string",
              "null"
            ]
          },
          "fields": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ImportField"
            }
          }
        },
        "required": [
          "kind",
          "label",
          "description",
          "available",
          "unavailableReason",
          "fields"
        ]
      },
      "ImportKindList": {
        "type": "object",
        "properties": {
          "kinds": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ImportKindInfo"
            }
          },
          "extensions": {
            "description": "Extensions accepted.",
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "maxBytes": {
            "type": "integer"
          },
          "maxRows": {
            "type": "integer"
          }
        },
        "required": [
          "kinds",
          "extensions",
          "maxBytes",
          "maxRows"
        ]
      },
      "CreateImportRequest": {
        "type": "object",
        "properties": {
          "kind": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ImportKind"
              }
            ]
          },
          "fileName": {
            "type": "string"
          },
          "contentType": {
            "type": "string"
          },
          "sizeBytes": {
            "type": "integer"
          },
          "clientId": {
            "type": "string",
            "format": "uuid",
            "description": "Trial balance: whose."
          },
          "periodEnd": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31",
            "description": "Trial balance: the period of the accounts it goes in."
          },
          "periodStart": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31",
            "description": "Left out: twelve months."
          },
          "use": {
            "description": "comparatives: the file’s balances become last year’s column.",
            "allOf": [
              {
                "$ref": "#/components/schemas/ImportTbUse"
              }
            ]
          }
        },
        "required": [
          "kind",
          "fileName",
          "sizeBytes"
        ]
      },
      "ImportUpload": {
        "type": "object",
        "properties": {
          "url": {
            "type": "string"
          },
          "method": {
            "type": "string"
          },
          "headers": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            }
          }
        },
        "required": [
          "url",
          "method",
          "headers"
        ]
      },
      "ImportCreated": {
        "type": "object",
        "properties": {
          "batch": {
            "$ref": "#/components/schemas/ImportBatch"
          },
          "upload": {
            "description": "PUT the file here, then POST …/uploaded.",
            "allOf": [
              {
                "$ref": "#/components/schemas/ImportUpload"
              }
            ]
          }
        },
        "required": [
          "batch",
          "upload"
        ]
      },
      "ImportLayoutRequest": {
        "type": "object",
        "properties": {
          "sheet": {
            "type": "string"
          },
          "headerLine": {
            "type": "integer",
            "description": "The line or row the headings are on."
          }
        }
      },
      "ColumnChoice": {
        "type": "object",
        "properties": {
          "column": {
            "type": "integer"
          },
          "field": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "column",
          "field"
        ]
      },
      "ImportMappingRequest": {
        "type": "object",
        "properties": {
          "columns": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ColumnChoice"
            }
          }
        },
        "required": [
          "columns"
        ]
      },
      "ImportRowStatus": {
        "type": "string",
        "enum": [
          "unchecked",
          "ready",
          "warning",
          "error",
          "duplicate"
        ]
      },
      "ImportRowDecision": {
        "type": "string",
        "enum": [
          "create",
          "fill_blanks",
          "apply",
          "skip"
        ]
      },
      "ImportRowOutcome": {
        "type": "string",
        "enum": [
          "pending",
          "created",
          "updated",
          "applied",
          "skipped",
          "failed",
          "undone",
          "kept"
        ]
      },
      "ImportMatchHow": {
        "type": "string",
        "enum": [
          "utr",
          "company_number",
          "name"
        ]
      },
      "ImportRow": {
        "type": "object",
        "properties": {
          "line": {
            "type": "integer"
          },
          "label": {
            "type": "string"
          },
          "status": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ImportRowStatus"
              }
            ]
          },
          "decision": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ImportRowDecision"
              }
            ]
          },
          "outcome": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ImportRowOutcome"
              }
            ]
          },
          "outcomeNote": {
            "type": [
              "string",
              "null"
            ]
          },
          "errors": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "warnings": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "values": {
            "type": [
              "object",
              "null"
            ],
            "additionalProperties": true,
            "description": "What was read. Money is integer pence."
          },
          "matchClientId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "matchClientName": {
            "type": [
              "string",
              "null"
            ]
          },
          "matchHow": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/ImportMatchHow"
              },
              {
                "type": "null"
              }
            ]
          }
        },
        "description": "One row of the file.",
        "required": [
          "line",
          "label",
          "status",
          "decision",
          "outcome",
          "outcomeNote",
          "errors",
          "warnings",
          "values",
          "matchClientId",
          "matchClientName",
          "matchHow"
        ]
      },
      "ImportRowPage": {
        "type": "object",
        "properties": {
          "rows": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ImportRow"
            }
          },
          "nextAfter": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Pass as `after` for the next page."
          }
        },
        "required": [
          "rows",
          "nextAfter"
        ]
      },
      "ImportRowPatchRequest": {
        "type": "object",
        "properties": {
          "decision": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ImportRowDecision"
              }
            ]
          },
          "entityType": {
            "type": "string",
            "description": "The client type, when the file didn’t give one Tolvi knows."
          },
          "statementLine": {
            "type": "string",
            "description": "Trial balance: the statement line for this account."
          }
        }
      },
      "ImportBulkDecisionRequest": {
        "type": "object",
        "properties": {
          "status": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ImportRowStatus"
              }
            ]
          },
          "decision": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ImportRowDecision"
              }
            ]
          }
        },
        "required": [
          "status",
          "decision"
        ]
      },
      "ImportConfirmRequest": {
        "type": "object",
        "properties": {
          "expectedRows": {
            "type": "integer",
            "description": "How many rows the person saw would come in. Refused if that has changed."
          }
        },
        "description": "A person confirming what they have seen.",
        "required": [
          "expectedRows"
        ]
      },
      "HealthStatus": {
        "type": "string",
        "enum": [
          "ok"
        ]
      },
      "DatabaseStatus": {
        "type": "string",
        "enum": [
          "up",
          "down"
        ]
      },
      "Health": {
        "type": "object",
        "properties": {
          "status": {
            "allOf": [
              {
                "$ref": "#/components/schemas/HealthStatus"
              }
            ]
          },
          "db": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DatabaseStatus"
              }
            ]
          }
        },
        "required": [
          "status",
          "db"
        ]
      },
      "ProtectedResourceMetadata": {
        "type": "object",
        "properties": {
          "resource": {
            "type": "string",
            "format": "uri"
          },
          "authorization_servers": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "scopes_supported": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "bearer_methods_supported": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "resource_name": {
            "type": "string"
          }
        },
        "description": "RFC 9728 protected-resource metadata.",
        "required": [
          "resource",
          "authorization_servers",
          "scopes_supported",
          "bearer_methods_supported",
          "resource_name"
        ]
      },
      "SignInApp": {
        "type": "string",
        "enum": [
          "web",
          "books"
        ]
      },
      "AuthMode": {
        "type": "string",
        "enum": [
          "dev",
          "oidc"
        ]
      },
      "AuthConfig": {
        "type": "object",
        "properties": {
          "mode": {
            "allOf": [
              {
                "$ref": "#/components/schemas/AuthMode"
              }
            ]
          },
          "issuer": {
            "type": "string",
            "description": "OIDC issuer (oidc mode)."
          },
          "clientId": {
            "type": "string"
          },
          "audience": {
            "type": [
              "string",
              "null"
            ]
          },
          "scope": {
            "type": "string"
          },
          "signupOpen": {
            "type": "boolean",
            "description": "Whether new firms and businesses can sign themselves up. When false, people join only by invitation."
          }
        },
        "description": "What the web app needs to start sign-in.",
        "required": [
          "mode",
          "signupOpen"
        ]
      },
      "MembershipRole": {
        "type": "string",
        "enum": [
          "owner",
          "admin",
          "staff"
        ]
      },
      "StaffRole": {
        "type": "string",
        "enum": [
          "partner",
          "manager",
          "reviewer",
          "preparer",
          "admin"
        ]
      },
      "TenantKind": {
        "type": "string",
        "enum": [
          "practice",
          "business"
        ],
        "description": "practice: an accountancy firm. business: a business in Tolvi Books (a Books-app sign-in lists only these; any other sign-in only practices)."
      },
      "FirmMembership": {
        "type": "object",
        "properties": {
          "firmId": {
            "type": "string",
            "format": "uuid"
          },
          "firmName": {
            "type": "string"
          },
          "role": {
            "allOf": [
              {
                "$ref": "#/components/schemas/MembershipRole"
              }
            ]
          },
          "staffRole": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/StaffRole"
              },
              {
                "type": "null"
              }
            ]
          },
          "tenantKind": {
            "description": "practice: an accountancy firm. business: a business in Tolvi Books (a Books-app sign-in lists only these; any other sign-in only practices).",
            "allOf": [
              {
                "$ref": "#/components/schemas/TenantKind"
              }
            ]
          },
          "authOrgId": {
            "type": [
              "string",
              "null"
            ],
            "description": "The firm’s identity-provider organisation, if it has one. A practice’s web app signs in through it."
          }
        },
        "required": [
          "firmId",
          "firmName",
          "role",
          "staffRole"
        ]
      },
      "Me": {
        "type": "object",
        "properties": {
          "userId": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": [
              "string",
              "null"
            ]
          },
          "email": {
            "type": "string",
            "format": "email"
          },
          "memberships": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/FirmMembership"
            }
          },
          "platformStaff": {
            "type": "boolean",
            "description": "True when this person is Tolvi platform staff, so the web app can offer the staff-only pages without asking the staff access check (which refuses everyone else). The internal endpoints still run their own checks, MFA included."
          }
        },
        "required": [
          "userId",
          "name",
          "email",
          "memberships"
        ]
      },
      "OtherAppKind": {
        "type": "string",
        "enum": [
          "books",
          "practice"
        ],
        "description": "books: they are a member of a business in Tolvi Books. practice: they are a member of an accountancy firm. Null: neither beyond the kind this sign-in reaches."
      },
      "OtherApp": {
        "type": "object",
        "properties": {
          "otherApp": {
            "description": "books: they are a member of a business in Tolvi Books. practice: they are a member of an accountancy firm. Null: neither beyond the kind this sign-in reaches.",
            "oneOf": [
              {
                "$ref": "#/components/schemas/OtherAppKind"
              },
              {
                "type": "null"
              }
            ]
          },
          "otherAppInvitations": {
            "type": "boolean",
            "description": "An invitation of the other kind is waiting for their verified email address."
          },
          "otherAppUrl": {
            "type": "string",
            "description": "The address of the other app."
          }
        },
        "description": "Whether the signed-in person also belongs in the other Tolvi app, for routing after sign-in. A yes or no about their own identity: no firm names, ids or data of the other kind.",
        "required": [
          "otherApp",
          "otherAppInvitations",
          "otherAppUrl"
        ]
      },
      "ClientLink": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "personClientId": {
            "type": "string",
            "format": "uuid"
          },
          "personName": {
            "type": "string"
          },
          "companyClientId": {
            "type": "string",
            "format": "uuid"
          },
          "companyName": {
            "type": "string"
          },
          "isDirector": {
            "type": "boolean"
          },
          "isShareholder": {
            "type": "boolean"
          },
          "shareholdingBps": {
            "type": [
              "integer",
              "null"
            ]
          },
          "nameInCompanyRecords": {
            "type": [
              "string",
              "null"
            ]
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "personClientId",
          "personName",
          "companyClientId",
          "companyName",
          "isDirector",
          "isShareholder",
          "shareholdingBps",
          "nameInCompanyRecords",
          "createdAt"
        ]
      },
      "ClientLinkList": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ClientLink"
            }
          }
        },
        "required": [
          "items"
        ]
      },
      "ClientLinkSide": {
        "type": "string",
        "enum": [
          "person",
          "company"
        ]
      },
      "CreateClientLinkRequest": {
        "type": "object",
        "properties": {
          "otherClientId": {
            "type": "string",
            "format": "uuid"
          },
          "thisClientIs": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ClientLinkSide"
              }
            ]
          },
          "isDirector": {
            "type": "boolean"
          },
          "isShareholder": {
            "type": "boolean"
          },
          "shareholdingBps": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Share of the dividends, in basis points: 5000 is 50%."
          },
          "nameInCompanyRecords": {
            "type": [
              "string",
              "null"
            ],
            "description": "The name on the company’s accounts and CT600A, if it isn’t the client’s."
          }
        },
        "description": "A person is a director or shareholder of a company. Both are clients of the firm.",
        "required": [
          "otherClientId",
          "thisClientIs"
        ]
      },
      "UpdateClientLinkRequest": {
        "type": "object",
        "properties": {
          "isDirector": {
            "type": "boolean"
          },
          "isShareholder": {
            "type": "boolean"
          },
          "shareholdingBps": {
            "type": [
              "integer",
              "null"
            ]
          },
          "nameInCompanyRecords": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      },
      "CrossProductSuggestionKind": {
        "type": "string",
        "enum": [
          "dividends",
          "loan",
          "partnership",
          "accounts"
        ]
      },
      "CrossProductSuggestion": {
        "type": "object",
        "properties": {
          "key": {
            "type": "string"
          },
          "kind": {
            "allOf": [
              {
                "$ref": "#/components/schemas/CrossProductSuggestionKind"
              }
            ]
          },
          "headline": {
            "type": "string"
          },
          "source": {
            "type": "string",
            "description": "Where it comes from, in words: product, client and period."
          },
          "note": {
            "type": "string",
            "description": "What to check first."
          },
          "suggestedPence": {
            "type": [
              "integer",
              "null"
            ],
            "description": "The suggested figure in integer pence. Null when it can’t be worked out, such as with no shareholding on the link."
          },
          "currentPence": {
            "type": [
              "integer",
              "null"
            ],
            "description": "What the target holds now, in integer pence."
          },
          "writesFigure": {
            "type": "boolean",
            "description": "Accepting writes a figure to the target. If false, accepting only records that a person has dealt with it."
          },
          "target": {
            "type": [
              "string",
              "null"
            ],
            "description": "The box or field it would change."
          },
          "fingerprint": {
            "type": "string"
          }
        },
        "description": "Something a linked client’s work in another product suggests. Never applied by itself: a person confirms it, and no figure moves until they do.",
        "required": [
          "key",
          "kind",
          "headline",
          "source",
          "note",
          "suggestedPence",
          "currentPence",
          "writesFigure",
          "target",
          "fingerprint"
        ]
      },
      "CrossProductDecisionKind": {
        "type": "string",
        "enum": [
          "accepted",
          "dismissed"
        ]
      },
      "CrossProductDecision": {
        "type": "object",
        "properties": {
          "key": {
            "type": "string"
          },
          "decision": {
            "allOf": [
              {
                "$ref": "#/components/schemas/CrossProductDecisionKind"
              }
            ]
          },
          "amountPence": {
            "type": [
              "integer",
              "null"
            ]
          },
          "source": {
            "type": "string"
          },
          "decidedByName": {
            "type": [
              "string",
              "null"
            ]
          },
          "decidedAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "key",
          "decision",
          "amountPence",
          "source",
          "decidedByName",
          "decidedAt"
        ]
      },
      "CrossProductSuggestions": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CrossProductSuggestion"
            }
          },
          "decisions": {
            "description": "What people have decided already, kept for the record.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CrossProductDecision"
            }
          },
          "hiddenSources": {
            "type": "integer",
            "description": "Sources this person can’t see because they don’t hold that product, so what’s from them isn’t shown."
          }
        },
        "required": [
          "items",
          "decisions",
          "hiddenSources"
        ]
      },
      "CrossProductTarget": {
        "type": "string",
        "enum": [
          "self_assessment",
          "corporation_tax",
          "accounts"
        ]
      },
      "DecideCrossProductSuggestionRequest": {
        "type": "object",
        "properties": {
          "product": {
            "allOf": [
              {
                "$ref": "#/components/schemas/CrossProductTarget"
              }
            ]
          },
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "key": {
            "type": "string"
          },
          "fingerprint": {
            "type": "string"
          },
          "decision": {
            "allOf": [
              {
                "$ref": "#/components/schemas/CrossProductDecisionKind"
              }
            ]
          },
          "amountPence": {
            "type": "integer",
            "description": "Integer pence: what to put in, if the person changed the figure."
          }
        },
        "required": [
          "product",
          "id",
          "key",
          "fingerprint",
          "decision"
        ]
      },
      "ClientStatus": {
        "type": "string",
        "enum": [
          "prospect",
          "active",
          "former"
        ]
      },
      "ClientConnectionState": {
        "type": "string",
        "enum": [
          "connected",
          "reconnect",
          "error",
          "not_connected"
        ]
      },
      "EntityType": {
        "type": "string",
        "enum": [
          "LTD_FRS102_1A",
          "LTD_FRS105_MICRO",
          "LLP",
          "SOLE_TRADER",
          "INDIVIDUAL",
          "PARTNERSHIP",
          "TRUST",
          "ESTATE",
          "CHARITY_UNINCORPORATED",
          "CHARITY_TRUST",
          "CIO",
          "SCIO",
          "CHARITABLE_COMPANY"
        ]
      },
      "Software": {
        "type": "string",
        "enum": [
          "xero",
          "qbo",
          "sage",
          "freeagent",
          "tolvi_books",
          "manual"
        ]
      },
      "Client": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "firmId": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string",
            "example": "Hartley Joinery Ltd"
          },
          "entityType": {
            "allOf": [
              {
                "$ref": "#/components/schemas/EntityType"
              }
            ]
          },
          "companyNumber": {
            "type": [
              "string",
              "null"
            ],
            "example": "01234567",
            "description": "Companies House number."
          },
          "yearEndDay": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 1,
            "maximum": 31,
            "description": "Financial year end day (with yearEndMonth); null when not known."
          },
          "yearEndMonth": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 1,
            "maximum": 12,
            "description": "Financial year end month (1-12)."
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "status": {
            "description": "Prospect, active or former.",
            "allOf": [
              {
                "$ref": "#/components/schemas/ClientStatus"
              }
            ]
          },
          "latestPeriodEnd": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31",
            "description": "Lists only: the period end of the client’s latest engagement (null when it has none), so a year end can be shown when yearEndDay/yearEndMonth are not set."
          },
          "partnerId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid",
            "description": "Lists only: the partner on the client’s latest engagement."
          },
          "managerId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid",
            "description": "Lists only: the manager on the client’s latest engagement."
          },
          "connection": {
            "description": "Lists only: connected (Tolvi can read the books), reconnect (access expired or removed), error (the last call failed) or not_connected (manual upload).",
            "allOf": [
              {
                "$ref": "#/components/schemas/ClientConnectionState"
              }
            ]
          },
          "connectionProvider": {
            "type": [
              "string",
              "null"
            ],
            "example": "xero",
            "description": "Lists only: the client’s source: connected software (xero, quickbooks, sage or freeagent), or tolvi_books when the client’s books are in Tolvi Books and that is the source in use."
          },
          "nextDueDate": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31",
            "description": "Lists only: the earliest filing deadline among engagements not yet complete."
          }
        },
        "required": [
          "id",
          "firmId",
          "name",
          "entityType",
          "companyNumber",
          "yearEndDay",
          "yearEndMonth",
          "createdAt"
        ]
      },
      "ClientPage": {
        "type": "object",
        "properties": {
          "rows": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Client"
            }
          },
          "nextCursor": {
            "type": [
              "string",
              "null"
            ],
            "description": "Opaque cursor for the next page (pass as `cursor`); null on the last page."
          },
          "pageSize": {
            "type": "integer",
            "minimum": 1,
            "maximum": 100,
            "description": "The page size that was used."
          },
          "total": {
            "type": "integer",
            "description": "Clients matching the search and filters (all pages)."
          }
        },
        "required": [
          "rows",
          "nextCursor",
          "pageSize",
          "total"
        ]
      },
      "DuplicateClientMatch": {
        "type": "string",
        "enum": [
          "name",
          "company_number"
        ],
        "description": "name: the same name ignoring case, punctuation and spacing (\"&\" = \"and\", \"Limited\" = \"Ltd\"); company_number: the same Companies House number."
      },
      "DuplicateClient": {
        "type": "object",
        "properties": {
          "client": {
            "$ref": "#/components/schemas/Client"
          },
          "matchedOn": {
            "type": "array",
            "description": "name: the same name ignoring case, punctuation and spacing (\"&\" = \"and\", \"Limited\" = \"Ltd\"); company_number: the same Companies House number.",
            "items": {
              "$ref": "#/components/schemas/DuplicateClientMatch"
            }
          }
        },
        "description": "An existing client that a new one may duplicate.",
        "required": [
          "client",
          "matchedOn"
        ]
      },
      "DuplicateClients": {
        "type": "object",
        "properties": {
          "matches": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/DuplicateClient"
            }
          }
        },
        "required": [
          "matches"
        ]
      },
      "CreateClientRequest": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 200
          },
          "entityType": {
            "allOf": [
              {
                "$ref": "#/components/schemas/EntityType"
              }
            ]
          },
          "companyNumber": {
            "type": [
              "string",
              "null"
            ],
            "pattern": "^(?:[0-9]{8}|[A-Z]{2}[0-9]{6})$",
            "description": "Companies House number (upper-cased on save)."
          },
          "yearEndDay": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 1,
            "maximum": 31,
            "description": "Financial year end day; send with yearEndMonth."
          },
          "yearEndMonth": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 1,
            "maximum": 12,
            "description": "Financial year end month."
          }
        },
        "required": [
          "name",
          "entityType"
        ]
      },
      "HubClientCounts": {
        "type": "object",
        "properties": {
          "active": {
            "type": "integer"
          },
          "prospect": {
            "type": "integer"
          },
          "former": {
            "type": "integer"
          }
        },
        "required": [
          "active",
          "prospect",
          "former"
        ]
      },
      "HubDeadline": {
        "type": "object",
        "properties": {
          "engagementId": {
            "type": "string",
            "format": "uuid"
          },
          "clientId": {
            "type": "string",
            "format": "uuid"
          },
          "clientName": {
            "type": "string"
          },
          "periodEnd": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "dueDate": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "daysLeft": {
            "type": "integer",
            "description": "Days from today to the deadline; negative when overdue."
          },
          "stageName": {
            "type": "string"
          }
        },
        "required": [
          "engagementId",
          "clientId",
          "clientName",
          "periodEnd",
          "dueDate",
          "daysLeft",
          "stageName"
        ]
      },
      "HubWork": {
        "type": "object",
        "properties": {
          "yourTurn": {
            "type": "integer",
            "description": "Your turn, due soon: the Work queue’s to-do view."
          },
          "toReview": {
            "type": "integer",
            "description": "Waiting for your review."
          },
          "overdue": {
            "type": "integer"
          },
          "dueIn30Days": {
            "type": "integer"
          },
          "nextDeadlines": {
            "description": "The next five filing deadlines.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/HubDeadline"
            }
          }
        },
        "description": "Engagements where you are on the team, from Working Papers.",
        "required": [
          "yourTurn",
          "toReview",
          "overdue",
          "dueIn30Days",
          "nextDeadlines"
        ]
      },
      "WorkItemProduct": {
        "type": "string",
        "enum": [
          "working_papers",
          "self_assessment",
          "accounts",
          "corporation_tax"
        ],
        "description": "The products counted: those you can use."
      },
      "WorkDeadlineKind": {
        "type": "string",
        "enum": [
          "companies_house",
          "charity_regulator",
          "self_assessment",
          "ct600",
          "ct_payment"
        ]
      },
      "SuiteDeadline": {
        "type": "object",
        "properties": {
          "product": {
            "allOf": [
              {
                "$ref": "#/components/schemas/WorkItemProduct"
              }
            ]
          },
          "itemId": {
            "type": "string",
            "format": "uuid"
          },
          "clientId": {
            "type": "string",
            "format": "uuid"
          },
          "clientName": {
            "type": "string"
          },
          "periodLabel": {
            "type": "string",
            "example": "2025/26"
          },
          "stageLabel": {
            "type": "string"
          },
          "kind": {
            "allOf": [
              {
                "$ref": "#/components/schemas/WorkDeadlineKind"
              }
            ]
          },
          "label": {
            "type": "string"
          },
          "dueDate": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "daysLeft": {
            "type": "integer",
            "description": "Days from today; negative when overdue."
          }
        },
        "description": "One deadline on one piece of work, in any product.",
        "required": [
          "product",
          "itemId",
          "clientId",
          "clientName",
          "periodLabel",
          "stageLabel",
          "kind",
          "label",
          "dueDate",
          "daysLeft"
        ]
      },
      "HubSuite": {
        "type": "object",
        "properties": {
          "products": {
            "type": "array",
            "description": "The products counted: those you can use.",
            "items": {
              "$ref": "#/components/schemas/WorkItemProduct"
            }
          },
          "yourTurn": {
            "type": "integer",
            "description": "You act next."
          },
          "toReview": {
            "type": "integer",
            "description": "Waiting for your review."
          },
          "overdue": {
            "type": "integer"
          },
          "dueIn30Days": {
            "type": "integer"
          },
          "nextDeadlines": {
            "description": "The next five deadlines, each with its product.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SuiteDeadline"
            }
          }
        },
        "description": "Your work across every product you can use. Counts are of work you answer for.",
        "required": [
          "products",
          "yourTurn",
          "toReview",
          "overdue",
          "dueIn30Days",
          "nextDeadlines"
        ]
      },
      "HubMeeting": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "title": {
            "type": "string"
          },
          "clientId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "clientName": {
            "type": [
              "string",
              "null"
            ]
          },
          "joinAt": {
            "type": "string",
            "format": "date-time"
          },
          "status": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "title",
          "clientId",
          "clientName",
          "joinAt",
          "status"
        ]
      },
      "HubHome": {
        "type": "object",
        "properties": {
          "clients": {
            "$ref": "#/components/schemas/HubClientCounts"
          },
          "work": {
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/HubWork"
              }
            ]
          },
          "suite": {
            "$ref": "#/components/schemas/HubSuite"
          },
          "meetingsToday": {
            "description": "Note-takers you sent to meetings today (UK time). Null without Meetings.",
            "type": [
              "array",
              "null"
            ],
            "items": {
              "$ref": "#/components/schemas/HubMeeting"
            }
          }
        },
        "description": "The accountant’s home page in one read. A product’s part is null when this person can’t use it.",
        "required": [
          "clients",
          "work",
          "meetingsToday"
        ]
      },
      "WorkItemStage": {
        "type": "string",
        "enum": [
          "not_started",
          "preparing",
          "returned",
          "in_review",
          "ready_to_file",
          "filing",
          "complete"
        ]
      },
      "WorkDeadline": {
        "type": "object",
        "properties": {
          "kind": {
            "allOf": [
              {
                "$ref": "#/components/schemas/WorkDeadlineKind"
              }
            ]
          },
          "label": {
            "type": "string",
            "example": "CT600 filing"
          },
          "date": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          }
        },
        "required": [
          "kind",
          "label",
          "date"
        ]
      },
      "WorkItem": {
        "type": "object",
        "properties": {
          "product": {
            "allOf": [
              {
                "$ref": "#/components/schemas/WorkItemProduct"
              }
            ]
          },
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "The engagement, return or set of accounts."
          },
          "clientId": {
            "type": "string",
            "format": "uuid"
          },
          "clientName": {
            "type": "string"
          },
          "periodLabel": {
            "type": "string",
            "example": "YE 31 Mar 2026"
          },
          "periodEnd": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "dueDate": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31",
            "description": "The filing date, by the rule the product uses."
          },
          "daysLeft": {
            "type": "integer",
            "description": "Days from today; negative when overdue."
          },
          "deadlines": {
            "description": "Corporation tax has a payment date as well as a filing date.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/WorkDeadline"
            }
          },
          "status": {
            "type": "string",
            "description": "The product’s own status."
          },
          "stage": {
            "allOf": [
              {
                "$ref": "#/components/schemas/WorkItemStage"
              }
            ]
          },
          "stageLabel": {
            "type": "string",
            "example": "In review"
          },
          "ownerId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid",
            "description": "Who acts next. Null when that is any partner, or nobody yet."
          },
          "ownerName": {
            "type": [
              "string",
              "null"
            ]
          },
          "openReviewPoints": {
            "type": "integer"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "description": "One piece of work: an engagement, a self assessment return, a set of accounts or a Company Tax Return.",
        "required": [
          "product",
          "id",
          "clientId",
          "clientName",
          "periodLabel",
          "periodEnd",
          "dueDate",
          "daysLeft",
          "deadlines",
          "status",
          "stage",
          "stageLabel",
          "ownerId",
          "ownerName",
          "openReviewPoints",
          "updatedAt"
        ]
      },
      "WorkItemTotals": {
        "type": "object",
        "properties": {
          "total": {
            "type": "integer",
            "description": "Every row this filter matches, before paging."
          },
          "overdue": {
            "type": "integer"
          },
          "dueIn30Days": {
            "type": "integer"
          },
          "workingPapers": {
            "type": "integer"
          },
          "selfAssessment": {
            "type": "integer"
          },
          "accounts": {
            "type": "integer"
          },
          "corporationTax": {
            "type": "integer"
          }
        },
        "required": [
          "total",
          "overdue",
          "dueIn30Days",
          "workingPapers",
          "selfAssessment",
          "accounts",
          "corporationTax"
        ]
      },
      "WorkItemPage": {
        "type": "object",
        "properties": {
          "rows": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/WorkItem"
            }
          },
          "nextCursor": {
            "type": [
              "string",
              "null"
            ],
            "description": "Opaque cursor for the next page (pass as `cursor`); null on the last page."
          },
          "pageSize": {
            "type": "integer",
            "minimum": 1,
            "maximum": 100,
            "description": "The page size that was used."
          },
          "totals": {
            "$ref": "#/components/schemas/WorkItemTotals"
          },
          "products": {
            "type": "array",
            "description": "The products looked in: those you can use.",
            "items": {
              "$ref": "#/components/schemas/WorkItemProduct"
            }
          }
        },
        "description": "Work across the products you can use, soonest deadline first.",
        "required": [
          "rows",
          "nextCursor",
          "pageSize",
          "totals",
          "products"
        ]
      },
      "HubWidgetKey": {
        "type": "string",
        "enum": [
          "my_deadlines",
          "team_workload",
          "deadlines_by_week",
          "overdue_at_risk",
          "awaiting_review",
          "open_review_points",
          "work_by_status",
          "completed_this_month",
          "recent_notifications",
          "meetings_today",
          "recently_opened",
          "changed_source_files",
          "ai_tokens",
          "imports_in_progress"
        ]
      },
      "HubWidgetDefinition": {
        "type": "object",
        "properties": {
          "key": {
            "allOf": [
              {
                "$ref": "#/components/schemas/HubWidgetKey"
              }
            ]
          },
          "title": {
            "type": "string"
          },
          "purpose": {
            "type": "string"
          },
          "dataSource": {
            "type": "string"
          },
          "audience": {
            "type": "string",
            "description": "Who can see it."
          },
          "w": {
            "type": "integer",
            "description": "Its usual width, in columns of twelve."
          },
          "h": {
            "type": "integer",
            "description": "Its usual height, in rows."
          },
          "scopes": {
            "type": "array",
            "description": "Whose work it can count; the first is the default. Empty when that doesn’t apply.",
            "items": {
              "type": "string",
              "enum": [
                "mine",
                "all"
              ]
            }
          },
          "byProduct": {
            "type": "boolean",
            "description": "Whether it can be narrowed to one app."
          }
        },
        "description": "One widget in the catalogue.",
        "required": [
          "key",
          "title",
          "purpose",
          "dataSource",
          "audience",
          "w",
          "h",
          "scopes",
          "byProduct"
        ]
      },
      "HubWidgetCatalogue": {
        "type": "object",
        "properties": {
          "widgets": {
            "description": "Only widgets you can see.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/HubWidgetDefinition"
            }
          },
          "products": {
            "type": "array",
            "description": "The apps whose work you can read.",
            "items": {
              "type": "string",
              "enum": [
                "working_papers",
                "self_assessment",
                "accounts",
                "corporation_tax"
              ]
            }
          }
        },
        "required": [
          "widgets",
          "products"
        ]
      },
      "HubWidgetScope": {
        "type": "string",
        "enum": [
          "mine",
          "all"
        ]
      },
      "HubWidgetFigureUnit": {
        "type": "string",
        "enum": [
          "count",
          "pence",
          "tokens"
        ]
      },
      "HubWidgetFigureTone": {
        "type": "string",
        "enum": [
          "neutral",
          "warning",
          "danger"
        ]
      },
      "HubWidgetFigure": {
        "type": "object",
        "properties": {
          "value": {
            "type": "integer",
            "description": "In integer pence when the unit is pence."
          },
          "unit": {
            "allOf": [
              {
                "$ref": "#/components/schemas/HubWidgetFigureUnit"
              }
            ]
          },
          "label": {
            "type": "string"
          },
          "tone": {
            "allOf": [
              {
                "$ref": "#/components/schemas/HubWidgetFigureTone"
              }
            ]
          }
        },
        "required": [
          "value",
          "unit",
          "label",
          "tone"
        ]
      },
      "HubWidgetChart": {
        "type": "string",
        "enum": [
          "none",
          "bars",
          "stacked_bars",
          "columns"
        ]
      },
      "HubWidgetWorkFilterScope": {
        "type": "string",
        "enum": [
          "mine",
          "review",
          "all"
        ]
      },
      "HubWidgetWorkFilter": {
        "type": "object",
        "properties": {
          "scope": {
            "allOf": [
              {
                "$ref": "#/components/schemas/HubWidgetWorkFilterScope"
              }
            ]
          },
          "product": {
            "allOf": [
              {
                "$ref": "#/components/schemas/WorkItemProduct"
              }
            ]
          },
          "stage": {
            "allOf": [
              {
                "$ref": "#/components/schemas/WorkItemStage"
              }
            ]
          },
          "ownerId": {
            "type": "string",
            "description": "A person’s id, or none for work nobody holds."
          },
          "dueFrom": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "dueTo": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "overdue": {
            "type": "boolean"
          },
          "atRisk": {
            "type": "boolean"
          },
          "openPoints": {
            "type": "boolean"
          },
          "includeCompleted": {
            "type": "boolean"
          },
          "updatedFrom": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          }
        },
        "description": "The query on GET /hub/work-items that shows the work behind a number."
      },
      "HubWidgetSegment": {
        "type": "object",
        "properties": {
          "key": {
            "type": "string"
          },
          "label": {
            "type": "string"
          },
          "value": {
            "type": "integer"
          },
          "filter": {
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/HubWidgetWorkFilter"
              }
            ]
          }
        },
        "required": [
          "key",
          "label",
          "value",
          "filter"
        ]
      },
      "HubWidgetBar": {
        "type": "object",
        "properties": {
          "key": {
            "type": "string"
          },
          "label": {
            "type": "string"
          },
          "value": {
            "type": "integer"
          },
          "filter": {
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/HubWidgetWorkFilter"
              }
            ]
          },
          "segments": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/HubWidgetSegment"
            }
          }
        },
        "required": [
          "key",
          "label",
          "value",
          "filter",
          "segments"
        ]
      },
      "HubWidgetLegendEntry": {
        "type": "object",
        "properties": {
          "key": {
            "type": "string"
          },
          "label": {
            "type": "string"
          }
        },
        "required": [
          "key",
          "label"
        ]
      },
      "HubWidgetLinkKind": {
        "type": "string",
        "enum": [
          "work_item",
          "meeting",
          "imports",
          "ai_settings",
          "notifications"
        ]
      },
      "HubWidgetLink": {
        "type": "object",
        "properties": {
          "kind": {
            "allOf": [
              {
                "$ref": "#/components/schemas/HubWidgetLinkKind"
              }
            ]
          },
          "product": {
            "allOf": [
              {
                "$ref": "#/components/schemas/WorkItemProduct"
              }
            ]
          },
          "id": {
            "type": "string",
            "format": "uuid"
          }
        },
        "description": "What a row or widget opens.",
        "required": [
          "kind"
        ]
      },
      "HubWidgetRow": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "detail": {
            "type": "string"
          },
          "date": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31"
          },
          "daysLeft": {
            "type": [
              "integer",
              "null"
            ]
          },
          "amountPence": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Integer pence."
          },
          "count": {
            "type": [
              "integer",
              "null"
            ]
          },
          "link": {
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/HubWidgetLink"
              }
            ]
          }
        },
        "required": [
          "id",
          "title",
          "detail",
          "date",
          "daysLeft",
          "amountPence",
          "count",
          "link"
        ]
      },
      "HubWidgetData": {
        "type": "object",
        "properties": {
          "key": {
            "allOf": [
              {
                "$ref": "#/components/schemas/HubWidgetKey"
              }
            ]
          },
          "asOf": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "summary": {
            "type": "string",
            "description": "One sentence saying what it shows: the text alternative for a chart."
          },
          "figure": {
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/HubWidgetFigure"
              }
            ]
          },
          "chart": {
            "allOf": [
              {
                "$ref": "#/components/schemas/HubWidgetChart"
              }
            ]
          },
          "bars": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/HubWidgetBar"
            }
          },
          "legend": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/HubWidgetLegendEntry"
            }
          },
          "rows": {
            "description": "At most twelve. total says how many there are.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/HubWidgetRow"
            }
          },
          "total": {
            "type": "integer"
          },
          "filter": {
            "description": "The work behind the whole widget; null when it isn’t work.",
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/HubWidgetWorkFilter"
              }
            ]
          },
          "link": {
            "description": "Where to go for more when it isn’t work.",
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/HubWidgetLink"
              }
            ]
          },
          "note": {
            "type": [
              "string",
              "null"
            ],
            "description": "Something the reader should know, such as what’s left out."
          }
        },
        "description": "What one widget shows, read from the product that holds it when you ask. Nothing is stored.",
        "required": [
          "key",
          "asOf",
          "summary",
          "figure",
          "chart",
          "bars",
          "legend",
          "rows",
          "total",
          "filter",
          "link",
          "note"
        ]
      },
      "HubDashboardKind": {
        "type": "string",
        "enum": [
          "preset",
          "private",
          "firm"
        ],
        "description": "preset: read only, can be duplicated. private: only its creator sees it. firm: everyone in the firm sees it."
      },
      "HubLayoutItem": {
        "type": "object",
        "properties": {
          "widget": {
            "allOf": [
              {
                "$ref": "#/components/schemas/HubWidgetKey"
              }
            ]
          },
          "w": {
            "type": "integer",
            "enum": [
              3,
              4,
              6,
              8,
              12
            ],
            "description": "Columns of twelve. A phone shows one column."
          },
          "h": {
            "type": "integer",
            "enum": [
              1,
              2,
              3
            ],
            "description": "Rows of the grid."
          },
          "scope": {
            "description": "mine: work you answer for. all: everyone’s. Left out: the widget’s default.",
            "allOf": [
              {
                "$ref": "#/components/schemas/HubWidgetScope"
              }
            ]
          },
          "product": {
            "description": "Only this app’s work.",
            "allOf": [
              {
                "$ref": "#/components/schemas/WorkItemProduct"
              }
            ]
          }
        },
        "description": "One widget on a dashboard. Its place in the list is its place on the grid.",
        "required": [
          "widget",
          "w",
          "h"
        ]
      },
      "HubDashboard": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "preset:<key> for a preset, otherwise the dashboard’s id.",
            "example": "preset:my_work"
          },
          "name": {
            "type": "string"
          },
          "description": {
            "type": [
              "string",
              "null"
            ]
          },
          "kind": {
            "description": "preset: read only, can be duplicated. private: only its creator sees it. firm: everyone in the firm sees it.",
            "allOf": [
              {
                "$ref": "#/components/schemas/HubDashboardKind"
              }
            ]
          },
          "canEdit": {
            "type": "boolean",
            "description": "Whether you may change or delete it: its creator, or for a shared one a manager and above."
          },
          "mine": {
            "type": "boolean"
          },
          "createdByName": {
            "type": [
              "string",
              "null"
            ],
            "description": "Who made it; null for a preset or someone who has left."
          },
          "layout": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/HubLayoutItem"
            }
          },
          "updatedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          }
        },
        "description": "A preset, or a dashboard someone saved.",
        "required": [
          "id",
          "name",
          "description",
          "kind",
          "canEdit",
          "mine",
          "createdByName",
          "layout",
          "updatedAt"
        ]
      },
      "HubDashboardList": {
        "type": "object",
        "properties": {
          "dashboards": {
            "description": "Presets for the apps you can use, then your own and those shared with the firm, by name.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/HubDashboard"
            }
          },
          "defaultId": {
            "type": "string",
            "description": "Which to open: your choice while it’s still there, otherwise the preset for your role."
          }
        },
        "required": [
          "dashboards",
          "defaultId"
        ]
      },
      "HubDashboardVisibility": {
        "type": "string",
        "enum": [
          "private",
          "firm"
        ],
        "description": "Left out: private."
      },
      "CreateHubDashboard": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "maxLength": 60
          },
          "visibility": {
            "description": "Left out: private.",
            "allOf": [
              {
                "$ref": "#/components/schemas/HubDashboardVisibility"
              }
            ]
          },
          "layout": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/HubLayoutItem"
            }
          }
        },
        "required": [
          "name",
          "layout"
        ]
      },
      "SetHubDefaultDashboard": {
        "type": "object",
        "properties": {
          "dashboard": {
            "type": "string",
            "description": "preset:<key> or a dashboard’s id.",
            "example": "preset:deadlines"
          }
        },
        "required": [
          "dashboard"
        ]
      },
      "UpdateHubDashboard": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "maxLength": 60
          },
          "visibility": {
            "allOf": [
              {
                "$ref": "#/components/schemas/HubDashboardVisibility"
              }
            ]
          },
          "layout": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/HubLayoutItem"
            }
          }
        },
        "description": "Only the fields sent are changed."
      },
      "ClientService": {
        "type": "string",
        "enum": [
          "accounts",
          "corporation_tax",
          "self_assessment",
          "vat",
          "payroll",
          "bookkeeping"
        ]
      },
      "ClientRecordPersonSource": {
        "type": "string",
        "enum": [
          "client",
          "latest_engagement"
        ],
        "description": "client: set on the record. latest_engagement: not set, so taken from the latest engagement’s team."
      },
      "ClientRecordPerson": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "source": {
            "description": "client: set on the record. latest_engagement: not set, so taken from the latest engagement’s team.",
            "allOf": [
              {
                "$ref": "#/components/schemas/ClientRecordPersonSource"
              }
            ]
          }
        },
        "required": [
          "id",
          "name",
          "source"
        ]
      },
      "ClientContact": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string",
            "example": "Jo Hartley"
          },
          "role": {
            "type": [
              "string",
              "null"
            ],
            "example": "Director"
          },
          "email": {
            "type": [
              "string",
              "null"
            ]
          },
          "phone": {
            "type": [
              "string",
              "null"
            ]
          },
          "isPrimary": {
            "type": "boolean",
            "description": "The person to contact first. At most one per client."
          },
          "appointedOn": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31",
            "description": "For a director: appointed during the year. Blank means throughout."
          },
          "resignedOn": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31",
            "description": "For a director: resigned during the year."
          }
        },
        "description": "A person at a client.",
        "required": [
          "id",
          "name",
          "role",
          "email",
          "phone",
          "isPrimary"
        ]
      },
      "ClientRecordEngagement": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "periodEnd": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "dueDate": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "status": {
            "type": "string",
            "example": "in_progress"
          },
          "stageName": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "periodEnd",
          "dueDate",
          "status",
          "stageName"
        ]
      },
      "ClientRecordWork": {
        "type": "object",
        "properties": {
          "current": {
            "description": "The latest year end.",
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/ClientRecordEngagement"
              }
            ]
          },
          "yearEnds": {
            "type": "integer"
          },
          "open": {
            "type": "integer",
            "description": "Engagements not yet complete."
          },
          "nextDueDate": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31",
            "description": "The earliest filing deadline among engagements not yet complete."
          }
        },
        "description": "From Working Papers.",
        "required": [
          "current",
          "yearEnds",
          "open",
          "nextDueDate"
        ]
      },
      "ClientRecordMeeting": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "title": {
            "type": "string"
          },
          "joinAt": {
            "type": "string",
            "format": "date-time"
          },
          "status": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "title",
          "joinAt",
          "status"
        ]
      },
      "ClientRecordMeetings": {
        "type": "object",
        "properties": {
          "total": {
            "type": "integer"
          },
          "openNextSteps": {
            "type": "integer",
            "description": "Next steps not yet sorted, across this client’s meetings."
          },
          "latest": {
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/ClientRecordMeeting"
              }
            ]
          }
        },
        "description": "From Meetings.",
        "required": [
          "total",
          "openNextSteps",
          "latest"
        ]
      },
      "ClientRecordBooks": {
        "type": "object",
        "properties": {
          "connectionLabel": {
            "type": [
              "string",
              "null"
            ],
            "example": "Xero",
            "description": "The connected software, if any."
          },
          "connectionStatus": {
            "type": [
              "string",
              "null"
            ],
            "description": "The connection’s state: active, expired, revoked or error."
          },
          "booksLinked": {
            "type": "boolean",
            "description": "The client is linked to a business in Tolvi Books."
          },
          "booksLive": {
            "type": "boolean",
            "description": "The link is live, so the firm can read those books."
          }
        },
        "description": "Where the client’s books are, from its connection and its Tolvi Books link.",
        "required": [
          "connectionLabel",
          "connectionStatus",
          "booksLinked",
          "booksLive"
        ]
      },
      "ClientRecordProductPeriod": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "periodLabel": {
            "type": "string",
            "example": "2025/26"
          },
          "periodEnd": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "status": {
            "type": "string",
            "description": "The product’s own status."
          },
          "stageLabel": {
            "type": "string",
            "example": "In review"
          },
          "dueDate": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          }
        },
        "description": "The latest return or set of accounts.",
        "required": [
          "id",
          "periodLabel",
          "periodEnd",
          "status",
          "stageLabel",
          "dueDate"
        ]
      },
      "ClientRecordProductWork": {
        "type": "object",
        "properties": {
          "total": {
            "type": "integer"
          },
          "open": {
            "type": "integer",
            "description": "Not yet filed, or for accounts not yet approved."
          },
          "nextDueDate": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31",
            "description": "The earliest filing deadline among those still open."
          },
          "latest": {
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/ClientRecordProductPeriod"
              }
            ]
          }
        },
        "description": "What a product holds for this client.",
        "required": [
          "total",
          "open",
          "nextDueDate",
          "latest"
        ]
      },
      "ClientRecord": {
        "type": "object",
        "properties": {
          "clientId": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "entityType": {
            "allOf": [
              {
                "$ref": "#/components/schemas/EntityType"
              }
            ]
          },
          "companyNumber": {
            "type": [
              "string",
              "null"
            ]
          },
          "yearEndDay": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 1,
            "maximum": 31
          },
          "yearEndMonth": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 1,
            "maximum": 12
          },
          "status": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ClientStatus"
              }
            ]
          },
          "services": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ClientService"
            }
          },
          "utr": {
            "type": [
              "string",
              "null"
            ],
            "description": "Unique Taxpayer Reference, ten digits."
          },
          "vatNumber": {
            "type": [
              "string",
              "null"
            ],
            "example": "GB123456789"
          },
          "payeReference": {
            "type": [
              "string",
              "null"
            ],
            "example": "123/AB456",
            "description": "Employer PAYE reference."
          },
          "registeredAddress": {
            "type": [
              "string",
              "null"
            ]
          },
          "principalActivity": {
            "type": [
              "string",
              "null"
            ],
            "description": "Accounts and Corporation Tax default from this."
          },
          "signatoryName": {
            "type": [
              "string",
              "null"
            ],
            "description": "Who usually signs the company’s accounts and returns. Accounts and Corporation Tax default from this."
          },
          "responsiblePartnerId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid",
            "description": "Set on the record; null when not set."
          },
          "clientManagerId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid",
            "description": "Set on the record; null when not set."
          },
          "responsiblePartner": {
            "description": "Who to show: the record’s, else the latest engagement’s.",
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/ClientRecordPerson"
              }
            ]
          },
          "clientManager": {
            "description": "Who to show: the record’s, else the latest engagement’s.",
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/ClientRecordPerson"
              }
            ]
          },
          "contacts": {
            "description": "Primary first, then by name.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ClientContact"
            }
          },
          "notes": {
            "type": "string",
            "description": "The client’s permanent notes."
          },
          "work": {
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/ClientRecordWork"
              }
            ]
          },
          "meetings": {
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/ClientRecordMeetings"
              }
            ]
          },
          "books": {
            "$ref": "#/components/schemas/ClientRecordBooks"
          },
          "selfAssessment": {
            "description": "From Self Assessment.",
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/ClientRecordProductWork"
              }
            ]
          },
          "accounts": {
            "description": "From Accounts.",
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/ClientRecordProductWork"
              }
            ]
          },
          "corporationTax": {
            "description": "From Corporation Tax.",
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/ClientRecordProductWork"
              }
            ]
          }
        },
        "description": "One client’s central record: what the firm holds, and what each product holds about them. A product’s part is null when this person or credential can’t use it.",
        "required": [
          "clientId",
          "name",
          "entityType",
          "companyNumber",
          "yearEndDay",
          "yearEndMonth",
          "status",
          "services",
          "utr",
          "vatNumber",
          "payeReference",
          "registeredAddress",
          "responsiblePartnerId",
          "clientManagerId",
          "responsiblePartner",
          "clientManager",
          "contacts",
          "notes",
          "work",
          "meetings",
          "books"
        ]
      },
      "ClientOverviewDeadline": {
        "type": "object",
        "properties": {
          "product": {
            "type": "string"
          },
          "itemId": {
            "type": "string",
            "format": "uuid"
          },
          "kind": {
            "type": "string"
          },
          "label": {
            "type": "string"
          },
          "periodLabel": {
            "type": "string"
          },
          "dueDate": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "daysLeft": {
            "type": "integer"
          }
        },
        "required": [
          "product",
          "itemId",
          "kind",
          "label",
          "periodLabel",
          "dueDate",
          "daysLeft"
        ]
      },
      "ClientOverviewUnavailable": {
        "type": "object",
        "properties": {
          "key": {
            "type": "string"
          },
          "label": {
            "type": "string"
          }
        },
        "required": [
          "key",
          "label"
        ]
      },
      "ClientOverviewLatest": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "periodLabel": {
            "type": "string"
          },
          "periodEnd": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "status": {
            "type": "string"
          },
          "stageLabel": {
            "type": "string"
          },
          "dueDate": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          }
        },
        "required": [
          "id",
          "periodLabel",
          "periodEnd",
          "status",
          "stageLabel",
          "dueDate"
        ]
      },
      "ClientOverviewPeriod": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "label": {
            "type": "string"
          },
          "periodEnd": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "status": {
            "type": "string"
          },
          "stageLabel": {
            "type": "string"
          },
          "dueDate": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "daysLeft": {
            "type": "integer"
          },
          "openReviewPoints": {
            "type": "integer"
          },
          "ownerName": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "id",
          "label",
          "periodEnd",
          "status",
          "stageLabel",
          "dueDate",
          "daysLeft",
          "openReviewPoints",
          "ownerName"
        ]
      },
      "ClientOverviewWorkingPapers": {
        "type": "object",
        "properties": {
          "total": {
            "type": "integer"
          },
          "open": {
            "type": "integer"
          },
          "nextDueDate": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31"
          },
          "latest": {
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/ClientOverviewLatest"
              }
            ]
          },
          "openReviewPoints": {
            "type": "integer"
          },
          "periods": {
            "description": "The latest six, newest first.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ClientOverviewPeriod"
            }
          },
          "software": {
            "type": [
              "string",
              "null"
            ]
          },
          "syncState": {
            "type": [
              "string",
              "null"
            ]
          },
          "lastSyncedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "filedOn": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31"
          },
          "openPoints": {
            "type": "integer"
          }
        },
        "required": [
          "total",
          "open",
          "nextDueDate",
          "latest",
          "openReviewPoints",
          "periods",
          "software",
          "syncState",
          "lastSyncedAt",
          "filedOn",
          "openPoints"
        ]
      },
      "ClientOverviewAccountsFigures": {
        "type": "object",
        "properties": {
          "turnoverPence": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Pence."
          },
          "profitPence": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Pence. Negative for a loss."
          },
          "netAssetsPence": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Pence."
          },
          "nextStep": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "turnoverPence",
          "profitPence",
          "netAssetsPence",
          "nextStep"
        ]
      },
      "ClientOverviewAccounts": {
        "type": "object",
        "properties": {
          "total": {
            "type": "integer"
          },
          "open": {
            "type": "integer"
          },
          "nextDueDate": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31"
          },
          "latest": {
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/ClientOverviewLatest"
              }
            ]
          },
          "openReviewPoints": {
            "type": "integer"
          },
          "periods": {
            "description": "The latest six, newest first.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ClientOverviewPeriod"
            }
          },
          "framework": {
            "type": [
              "string",
              "null"
            ]
          },
          "approvedOn": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31"
          },
          "signatoryName": {
            "type": [
              "string",
              "null"
            ]
          },
          "figures": {
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/ClientOverviewAccountsFigures"
              }
            ]
          }
        },
        "required": [
          "total",
          "open",
          "nextDueDate",
          "latest",
          "openReviewPoints",
          "periods",
          "framework",
          "approvedOn",
          "signatoryName",
          "figures"
        ]
      },
      "ClientOverviewCorporationTax": {
        "type": "object",
        "properties": {
          "total": {
            "type": "integer"
          },
          "open": {
            "type": "integer"
          },
          "nextDueDate": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31"
          },
          "latest": {
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/ClientOverviewLatest"
              }
            ]
          },
          "openReviewPoints": {
            "type": "integer"
          },
          "periods": {
            "description": "The latest six, newest first.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ClientOverviewPeriod"
            }
          },
          "taxDuePence": {
            "type": [
              "integer",
              "null"
            ],
            "description": "On the latest return, pence. Negative when overpaid."
          },
          "paymentDue": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31"
          },
          "filedElsewhereOn": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31",
            "description": "The latest date a person recorded a return as filed outside Tolvi. Not HMRC’s word."
          }
        },
        "required": [
          "total",
          "open",
          "nextDueDate",
          "latest",
          "openReviewPoints",
          "periods",
          "taxDuePence",
          "paymentDue",
          "filedElsewhereOn"
        ]
      },
      "ClientOverviewSelfAssessment": {
        "type": "object",
        "properties": {
          "total": {
            "type": "integer"
          },
          "open": {
            "type": "integer"
          },
          "nextDueDate": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31"
          },
          "latest": {
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/ClientOverviewLatest"
              }
            ]
          },
          "openReviewPoints": {
            "type": "integer"
          },
          "periods": {
            "description": "The latest six, newest first.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ClientOverviewPeriod"
            }
          },
          "taxDuePence": {
            "type": [
              "integer",
              "null"
            ],
            "description": "On the latest return, pence. Negative when overpaid."
          },
          "returnType": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "total",
          "open",
          "nextDueDate",
          "latest",
          "openReviewPoints",
          "periods",
          "taxDuePence",
          "returnType"
        ]
      },
      "ClientOverviewVatLatest": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "periodKey": {
            "type": "string"
          },
          "periodStart": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "periodEnd": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "status": {
            "type": "string"
          },
          "netDuePence": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Box 5, pence. Negative when reclaimed."
          },
          "vrn": {
            "type": "string",
            "description": "The number this return was prepared under."
          }
        },
        "required": [
          "id",
          "periodKey",
          "periodStart",
          "periodEnd",
          "status",
          "netDuePence",
          "vrn"
        ]
      },
      "ClientOverviewVat": {
        "type": "object",
        "properties": {
          "total": {
            "type": "integer"
          },
          "vatNumber": {
            "type": [
              "string",
              "null"
            ],
            "description": "On the record."
          },
          "latest": {
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/ClientOverviewVatLatest"
              }
            ]
          }
        },
        "required": [
          "total",
          "vatNumber",
          "latest"
        ]
      },
      "ClientOverview": {
        "type": "object",
        "properties": {
          "clientId": {
            "type": "string",
            "format": "uuid"
          },
          "today": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "record": {
            "$ref": "#/components/schemas/ClientRecord"
          },
          "deadlines": {
            "description": "Open work’s next deadlines across the products you can use, soonest first.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ClientOverviewDeadline"
            }
          },
          "unavailable": {
            "description": "Products you can’t use, so their parts are null.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ClientOverviewUnavailable"
            }
          },
          "workingPapers": {
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/ClientOverviewWorkingPapers"
              }
            ]
          },
          "accounts": {
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/ClientOverviewAccounts"
              }
            ]
          },
          "corporationTax": {
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/ClientOverviewCorporationTax"
              }
            ]
          },
          "selfAssessment": {
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/ClientOverviewSelfAssessment"
              }
            ]
          },
          "vat": {
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/ClientOverviewVat"
              }
            ]
          },
          "books": {
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/ClientRecordBooks"
              }
            ]
          },
          "meetings": {
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/ClientRecordMeetings"
              }
            ]
          }
        },
        "required": [
          "clientId",
          "today",
          "createdAt",
          "record",
          "deadlines",
          "unavailable",
          "workingPapers",
          "accounts",
          "corporationTax",
          "selfAssessment",
          "vat",
          "books",
          "meetings"
        ]
      },
      "PeriodChainStepKey": {
        "type": "string",
        "enum": [
          "books",
          "file",
          "accounts",
          "corporation_tax",
          "filing"
        ]
      },
      "PeriodChainStep": {
        "type": "object",
        "properties": {
          "key": {
            "allOf": [
              {
                "$ref": "#/components/schemas/PeriodChainStepKey"
              }
            ]
          },
          "label": {
            "type": "string"
          },
          "itemId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid",
            "description": "The file, set or return for this year end. Null for books and filing, and when none has been started."
          },
          "stage": {
            "type": [
              "string",
              "null"
            ],
            "description": "not_started, preparing, returned, in_review, ready_to_file, filing or complete. Null when nothing has been started."
          },
          "statusLabel": {
            "type": "string",
            "description": "The status words the product itself shows."
          },
          "dueDate": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31",
            "description": "When the work is due or, on filing, the date a person recorded it as filed outside Tolvi."
          },
          "openReviewPoints": {
            "type": "integer"
          },
          "coming": {
            "type": "boolean",
            "description": "Not open in Tolvi yet."
          }
        },
        "required": [
          "key",
          "label",
          "itemId",
          "stage",
          "statusLabel",
          "dueDate",
          "openReviewPoints",
          "coming"
        ]
      },
      "PeriodChain": {
        "type": "object",
        "properties": {
          "clientId": {
            "type": "string",
            "format": "uuid"
          },
          "periodEnd": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31",
            "description": "The year end shown. Null when the client has no work yet."
          },
          "periods": {
            "description": "Year ends with work, newest first, the latest six.",
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "steps": {
            "description": "In order. Only products you can use, and only those the client’s type can have.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PeriodChainStep"
            }
          }
        },
        "required": [
          "clientId",
          "periodEnd",
          "periods",
          "steps"
        ]
      },
      "UpdateClientRecordRequest": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "maxLength": 200,
            "description": "The client’s name. Work in progress reads it from here; an approved return or accounts keep the name they were approved under."
          },
          "entityType": {
            "description": "What the client is. Decides what new work can start; work already started keeps what it started with.",
            "allOf": [
              {
                "$ref": "#/components/schemas/EntityType"
              }
            ]
          },
          "companyNumber": {
            "type": [
              "string",
              "null"
            ],
            "description": "Companies House number."
          },
          "yearEndDay": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 1,
            "maximum": 31,
            "description": "Year end day, sent with yearEndMonth."
          },
          "yearEndMonth": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 1,
            "maximum": 12,
            "description": "Year end month, sent with yearEndDay."
          },
          "status": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ClientStatus"
              }
            ]
          },
          "services": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ClientService"
            }
          },
          "utr": {
            "type": [
              "string",
              "null"
            ]
          },
          "vatNumber": {
            "type": [
              "string",
              "null"
            ]
          },
          "payeReference": {
            "type": [
              "string",
              "null"
            ]
          },
          "registeredAddress": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 500
          },
          "principalActivity": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 1000
          },
          "signatoryName": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 200,
            "description": "Who usually signs the company’s accounts and returns."
          },
          "responsiblePartnerId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid",
            "description": "Must be a partner in the firm."
          },
          "clientManagerId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid",
            "description": "Must be a manager or partner in the firm."
          }
        },
        "description": "Send only what changes; null or blank clears a field."
      },
      "RecordDirector": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string"
          },
          "appointedOn": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "resignedOn": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          }
        },
        "required": [
          "name"
        ]
      },
      "CompanyFacts": {
        "type": "object",
        "properties": {
          "name": {
            "type": [
              "string",
              "null"
            ],
            "description": "The client’s name on the record."
          },
          "companyNumber": {
            "type": [
              "string",
              "null"
            ],
            "description": "Companies House number on the record."
          },
          "registeredOffice": {
            "type": [
              "string",
              "null"
            ]
          },
          "principalActivity": {
            "type": [
              "string",
              "null"
            ]
          },
          "signatoryName": {
            "type": [
              "string",
              "null"
            ],
            "description": "The record’s, or the only serving director."
          },
          "directors": {
            "description": "Contacts whose role says director.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/RecordDirector"
            }
          }
        },
        "description": "What the client’s record says about the company. Accounts and Corporation Tax start from this; a person chooses to save a change back.",
        "required": [
          "name",
          "companyNumber",
          "registeredOffice",
          "principalActivity",
          "signatoryName",
          "directors"
        ]
      },
      "SaveDirectorsRequest": {
        "type": "object",
        "properties": {
          "directors": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/RecordDirector"
            }
          }
        },
        "description": "Adds these people as contacts with the role Director, or updates their dates. Nobody is removed.",
        "required": [
          "directors"
        ]
      },
      "CreateClientContactRequest": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 200
          },
          "role": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 100
          },
          "email": {
            "type": [
              "string",
              "null"
            ],
            "format": "email"
          },
          "phone": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 40
          },
          "isPrimary": {
            "type": "boolean",
            "description": "The client’s first contact is primary anyway. Setting this moves it from whoever had it."
          },
          "appointedOn": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31"
          },
          "resignedOn": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31"
          }
        },
        "required": [
          "name"
        ]
      },
      "UpdateClientContactRequest": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 200
          },
          "role": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 100
          },
          "email": {
            "type": [
              "string",
              "null"
            ],
            "format": "email"
          },
          "phone": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 40
          },
          "isPrimary": {
            "type": "boolean",
            "description": "Setting this moves it from whoever had it."
          },
          "appointedOn": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31"
          },
          "resignedOn": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31"
          }
        },
        "description": "Send only what changes."
      },
      "ClientFieldModuleEntry": {
        "type": "object",
        "properties": {
          "key": {
            "type": "string"
          },
          "label": {
            "type": "string"
          }
        },
        "required": [
          "key",
          "label"
        ]
      },
      "ClientFieldType": {
        "type": "string",
        "enum": [
          "text",
          "enum",
          "person",
          "date",
          "money",
          "number"
        ]
      },
      "ClientFieldOption": {
        "type": "object",
        "properties": {
          "value": {
            "type": "string"
          },
          "label": {
            "type": "string"
          }
        },
        "required": [
          "value",
          "label"
        ]
      },
      "ClientField": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "example": "ct.due",
            "description": "The id to use in columns, filter and sort."
          },
          "module": {
            "type": "string",
            "example": "corporation_tax"
          },
          "label": {
            "type": "string"
          },
          "type": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ClientFieldType"
              }
            ]
          },
          "filterable": {
            "type": "boolean"
          },
          "sortable": {
            "type": "boolean"
          },
          "operators": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "The operators a condition on this field can use."
          },
          "options": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ClientFieldOption"
            }
          },
          "description": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "module",
          "label",
          "type",
          "filterable",
          "sortable",
          "operators"
        ]
      },
      "ClientFieldCatalogue": {
        "type": "object",
        "properties": {
          "modules": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ClientFieldModuleEntry"
            }
          },
          "defaultColumns": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "fields": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ClientField"
            }
          }
        },
        "required": [
          "modules",
          "defaultColumns",
          "fields"
        ]
      },
      "ClientListRow": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "values": {
            "type": "object",
            "additionalProperties": {
              "oneOf": [
                {
                  "type": "string"
                },
                {
                  "type": "integer"
                }
              ]
            },
            "description": "By field id. Money is integer pence; dates are ISO; a person is their name."
          }
        },
        "required": [
          "id",
          "values"
        ]
      },
      "ClientListHiddenField": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "label": {
            "type": "string"
          },
          "module": {
            "type": "string"
          },
          "moduleLabel": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "label",
          "module",
          "moduleLabel"
        ]
      },
      "ClientListPage": {
        "type": "object",
        "properties": {
          "rows": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ClientListRow"
            }
          },
          "columns": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "The columns returned, in order."
          },
          "page": {
            "type": "integer"
          },
          "pageSize": {
            "type": "integer"
          },
          "total": {
            "type": "integer"
          },
          "hiddenFields": {
            "description": "Fields asked for from products you can’t use: left out of the columns, and conditions on them not applied.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ClientListHiddenField"
            }
          }
        },
        "required": [
          "rows",
          "columns",
          "page",
          "pageSize",
          "total",
          "hiddenFields"
        ]
      },
      "ClientViewVisibility": {
        "type": "string",
        "enum": [
          "private",
          "firm"
        ]
      },
      "ClientListSortDirection": {
        "type": "string",
        "enum": [
          "asc",
          "desc"
        ]
      },
      "ClientListSort": {
        "type": "object",
        "properties": {
          "field": {
            "type": "string"
          },
          "dir": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ClientListSortDirection"
              }
            ]
          }
        },
        "required": [
          "field",
          "dir"
        ]
      },
      "ClientListView": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "visibility": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ClientViewVisibility"
              }
            ]
          },
          "columns": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "filter": {
            "type": "object",
            "additionalProperties": true,
            "description": "`{ match: \"all\" | \"any\", conditions: [{ field, operator, value } | group] }`, nesting three groups deep and 40 conditions at most."
          },
          "sort": {
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/ClientListSort"
              }
            ]
          },
          "createdBy": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "createdByName": {
            "type": [
              "string",
              "null"
            ]
          },
          "isDefault": {
            "type": "boolean",
            "description": "The view you open the client list on."
          },
          "canEdit": {
            "type": "boolean",
            "description": "Whether you can change or delete it."
          },
          "hiddenFields": {
            "description": "What this view uses from products you can’t use.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ClientListHiddenField"
            }
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "name",
          "visibility",
          "columns",
          "filter",
          "sort",
          "createdBy",
          "createdByName",
          "isDefault",
          "canEdit",
          "hiddenFields",
          "updatedAt"
        ]
      },
      "ClientListViews": {
        "type": "object",
        "properties": {
          "views": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ClientListView"
            }
          },
          "defaultViewId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          }
        },
        "required": [
          "views",
          "defaultViewId"
        ]
      },
      "CreateClientListViewRequest": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "maxLength": 80
          },
          "visibility": {
            "description": "private (the default) or firm: everyone in the practice.",
            "allOf": [
              {
                "$ref": "#/components/schemas/ClientViewVisibility"
              }
            ]
          },
          "columns": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "filter": {
            "type": "object",
            "additionalProperties": true,
            "description": "`{ match: \"all\" | \"any\", conditions: [{ field, operator, value } | group] }`, nesting three groups deep and 40 conditions at most."
          },
          "sort": {
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/ClientListSort"
              }
            ]
          }
        },
        "required": [
          "name",
          "columns"
        ]
      },
      "UpdateClientListViewRequest": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "maxLength": 80
          },
          "visibility": {
            "description": "Only whoever made the view can change this.",
            "allOf": [
              {
                "$ref": "#/components/schemas/ClientViewVisibility"
              }
            ]
          },
          "columns": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "filter": {
            "type": "object",
            "additionalProperties": true,
            "description": "`{ match: \"all\" | \"any\", conditions: [{ field, operator, value } | group] }`, nesting three groups deep and 40 conditions at most."
          },
          "sort": {
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/ClientListSort"
              }
            ]
          }
        }
      },
      "DuplicateClientListViewRequest": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "maxLength": 80
          }
        }
      },
      "AccountsFramework": {
        "type": "string",
        "enum": [
          "FRS105",
          "FRS102_1A",
          "FRS102_FULL",
          "NON_STATUTORY",
          "CHARITY_SORP",
          "CHARITY_RP"
        ]
      },
      "AccountsEntity": {
        "type": "string",
        "enum": [
          "company",
          "llp",
          "sole_trader",
          "partnership",
          "charity"
        ]
      },
      "AccountsSource": {
        "type": "string",
        "enum": [
          "direct",
          "working_papers"
        ]
      },
      "AccountsStatus": {
        "type": "string",
        "enum": [
          "draft",
          "in_review",
          "approved"
        ]
      },
      "AccountsSetSummary": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "clientId": {
            "type": "string",
            "format": "uuid"
          },
          "clientName": {
            "type": "string"
          },
          "dueDate": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31",
            "description": "When they’re due at Companies House (CA 2006 s442, for an LLP as applied by SI 2008/1911). Non-statutory accounts have no such date: this is the self assessment date they work towards."
          },
          "periodStart": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "periodEnd": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "framework": {
            "allOf": [
              {
                "$ref": "#/components/schemas/AccountsFramework"
              }
            ]
          },
          "entity": {
            "allOf": [
              {
                "$ref": "#/components/schemas/AccountsEntity"
              }
            ]
          },
          "source": {
            "allOf": [
              {
                "$ref": "#/components/schemas/AccountsSource"
              }
            ]
          },
          "status": {
            "allOf": [
              {
                "$ref": "#/components/schemas/AccountsStatus"
              }
            ]
          },
          "approvedOn": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          },
          "revisionNumber": {
            "type": "integer",
            "description": "0 for the original accounts, 1 for the first revision."
          },
          "supersededBySetId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid",
            "description": "Set once approved revised accounts have replaced these."
          },
          "nextStep": {
            "type": [
              "string",
              "null"
            ],
            "description": "In the list: the first thing stopping approval. Null when nothing is. A linked file isn’t read for the list, so open the set to see whether it has changed."
          },
          "blockingProblems": {
            "type": "integer",
            "description": "In the list: how many problems stop approval."
          }
        },
        "required": [
          "id",
          "clientId",
          "clientName",
          "periodStart",
          "periodEnd",
          "framework",
          "entity",
          "source",
          "status",
          "approvedOn",
          "updatedAt"
        ]
      },
      "AccountsSetList": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AccountsSetSummary"
            }
          }
        },
        "required": [
          "items"
        ]
      },
      "AccountsJurisdiction": {
        "type": "string",
        "enum": [
          "England and Wales",
          "Scotland",
          "Wales",
          "Northern Ireland"
        ]
      },
      "AccountsCompanyForm": {
        "type": "string",
        "enum": [
          "private_limited_by_shares",
          "private_limited_by_guarantee"
        ]
      },
      "AccountsDirector": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string"
          },
          "appointedOn": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "resignedOn": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "designated": {
            "type": "boolean",
            "description": "An LLP’s designated member."
          }
        },
        "required": [
          "name"
        ]
      },
      "AccountsCompany": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string"
          },
          "registeredNumber": {
            "type": "string"
          },
          "registeredOffice": {
            "type": "string"
          },
          "jurisdiction": {
            "allOf": [
              {
                "$ref": "#/components/schemas/AccountsJurisdiction"
              }
            ]
          },
          "form": {
            "allOf": [
              {
                "$ref": "#/components/schemas/AccountsCompanyForm"
              }
            ]
          },
          "directors": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AccountsDirector"
            }
          },
          "secretary": {
            "type": [
              "string",
              "null"
            ]
          },
          "principalActivity": {
            "type": "string"
          },
          "beingWoundUp": {
            "type": "boolean"
          }
        },
        "description": "The company, LLP or business as the accounts state it. `directors` holds an LLP’s members, or a proprietor or partners.",
        "required": [
          "name",
          "registeredNumber",
          "registeredOffice",
          "directors"
        ]
      },
      "CreateAccountsSetRequest": {
        "type": "object",
        "properties": {
          "clientId": {
            "type": "string",
            "format": "uuid"
          },
          "periodStart": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "periodEnd": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "priorStart": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31",
            "description": "With `priorEnd`. Left out for a first period: no comparatives are shown."
          },
          "priorEnd": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "framework": {
            "allOf": [
              {
                "$ref": "#/components/schemas/AccountsFramework"
              }
            ]
          },
          "company": {
            "description": "Left out: name, number and registered office come from the client record.",
            "allOf": [
              {
                "$ref": "#/components/schemas/AccountsCompany"
              }
            ]
          }
        },
        "description": "One set per client and period end. The client’s entity type decides what’s allowed: a company or LLP takes FRS 105, FRS 102 Section 1A or full FRS 102; a sole trader or partnership takes NON_STATUTORY.",
        "required": [
          "clientId",
          "periodStart",
          "periodEnd",
          "framework"
        ]
      },
      "AccountsSourceState": {
        "type": "object",
        "properties": {
          "source": {
            "allOf": [
              {
                "$ref": "#/components/schemas/AccountsSource"
              }
            ]
          },
          "engagementId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "sourceChanged": {
            "type": "boolean",
            "description": "The Working Papers file’s figures differ from this set’s. The set’s figures have not moved: refresh to bring them in."
          },
          "fileApproved": {
            "type": [
              "boolean",
              "null"
            ],
            "description": "Whether the file is approved. Null for a direct set."
          },
          "message": {
            "type": [
              "string",
              "null"
            ],
            "description": "In plain words, for the screen."
          }
        },
        "description": "Where the figures came from and whether that has moved on.",
        "required": [
          "source",
          "engagementId",
          "sourceChanged",
          "fileApproved",
          "message"
        ]
      },
      "AccountsEmployees": {
        "type": "object",
        "properties": {
          "thisYear": {
            "type": "integer",
            "minimum": 0
          },
          "lastYear": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 0
          }
        },
        "description": "Average persons employed (CA 2006 s411).",
        "required": [
          "thisYear",
          "lastYear"
        ]
      },
      "AccountsCommitments": {
        "type": "object",
        "properties": {
          "total": {
            "type": "array",
            "items": {
              "type": "integer"
            },
            "minItems": 2,
            "maxItems": 2,
            "description": "[this year, last year], integer pence."
          },
          "description": {
            "type": "string"
          },
          "pensions": {
            "type": "array",
            "items": {
              "type": "integer"
            },
            "minItems": 2,
            "maxItems": 2,
            "description": "[this year, last year], integer pence."
          },
          "groupUndertakings": {
            "type": "array",
            "items": {
              "type": "integer"
            },
            "minItems": 2,
            "maxItems": 2,
            "description": "[this year, last year], integer pence."
          },
          "participatingInterests": {
            "type": "array",
            "items": {
              "type": "integer"
            },
            "minItems": 2,
            "maxItems": 2,
            "description": "[this year, last year], integer pence."
          },
          "securityGiven": {
            "type": "string"
          }
        },
        "required": [
          "total",
          "description"
        ]
      },
      "AccountsDirectorAdvance": {
        "type": "object",
        "properties": {
          "director": {
            "type": "string"
          },
          "interestRate": {
            "type": "string"
          },
          "mainConditions": {
            "type": "string"
          },
          "opening": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "advanced": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "repaid": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "writtenOff": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "waived": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "closing": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          }
        },
        "description": "CA 2006 s413(3). Opening + advanced - repaid - written off - waived = closing.",
        "required": [
          "director",
          "interestRate",
          "mainConditions",
          "opening",
          "advanced",
          "repaid",
          "writtenOff",
          "waived",
          "closing"
        ]
      },
      "AccountsDirectorGuarantee": {
        "type": "object",
        "properties": {
          "director": {
            "type": "string"
          },
          "mainTerms": {
            "type": "string"
          },
          "maximumLiability": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "amountPaidOrIncurred": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          }
        },
        "required": [
          "director",
          "mainTerms",
          "maximumLiability",
          "amountPaidOrIncurred"
        ]
      },
      "AccountsParentUndertaking": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string"
          },
          "registeredOffice": {
            "type": "string"
          }
        },
        "required": [
          "name",
          "registeredOffice"
        ]
      },
      "AccountsGoingConcernBasis": {
        "type": "string",
        "enum": [
          "going_concern",
          "not_going_concern"
        ]
      },
      "AccountsGoingConcern": {
        "type": "object",
        "properties": {
          "basis": {
            "allOf": [
              {
                "$ref": "#/components/schemas/AccountsGoingConcernBasis"
              }
            ]
          },
          "disclosure": {
            "type": "string"
          }
        },
        "required": [
          "basis"
        ]
      },
      "AccountsAnalysisRow": {
        "type": "object",
        "properties": {
          "label": {
            "type": "string"
          },
          "values": {
            "type": "array",
            "items": {
              "type": "integer"
            },
            "minItems": 2,
            "maxItems": 2,
            "description": "[this year, last year], integer pence."
          }
        },
        "required": [
          "label",
          "values"
        ]
      },
      "AccountsShareCapital": {
        "type": "object",
        "properties": {
          "description": {
            "type": "string"
          },
          "rows": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AccountsAnalysisRow"
            }
          }
        },
        "required": [
          "description"
        ]
      },
      "AccountsExceptionalItem": {
        "type": "object",
        "properties": {
          "description": {
            "type": "string"
          },
          "values": {
            "type": "array",
            "items": {
              "type": "integer"
            },
            "minItems": 2,
            "maxItems": 2,
            "description": "[this year, last year], integer pence."
          }
        },
        "required": [
          "description",
          "values"
        ]
      },
      "AccountsPoliticalDonation": {
        "type": "object",
        "properties": {
          "recipient": {
            "type": "string"
          },
          "amount": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          }
        },
        "required": [
          "recipient",
          "amount"
        ]
      },
      "AccountsPoliticalGiving": {
        "type": "object",
        "properties": {
          "donations": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AccountsPoliticalDonation"
            }
          },
          "expenditure": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "nonUkContributions": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "whollyOwnedSubsidiaryOfUkCompany": {
            "type": "boolean"
          }
        }
      },
      "AccountsAuditExemption": {
        "type": "object",
        "properties": {
          "section477Taken": {
            "type": "boolean"
          },
          "section476NoticeGiven": {
            "type": "boolean"
          }
        },
        "required": [
          "section477Taken",
          "section476NoticeGiven"
        ]
      },
      "AccountsProposedSignatory": {
        "type": "object",
        "properties": {
          "signatoryName": {
            "type": "string"
          },
          "directorsReportSignatoryName": {
            "type": "string"
          }
        },
        "description": "Who is expected to sign. The approval itself is recorded through `approve`."
      },
      "AccountsExclusions": {
        "type": "object",
        "properties": {
          "publicCompany": {
            "type": "boolean"
          },
          "regulatedBusiness": {
            "type": "boolean"
          },
          "memberOfIneligibleGroup": {
            "type": "boolean"
          },
          "investmentOrFinancialHoldingOrCharity": {
            "type": "boolean"
          },
          "includedInGroupAccounts": {
            "type": "boolean"
          },
          "parentCompany": {
            "type": "boolean"
          }
        },
        "description": "Facts that take a company out of the regimes (CA 2006 ss384, 384B, 478)."
      },
      "AccountsAuditOpinion": {
        "type": "string",
        "enum": [
          "unqualified",
          "qualified",
          "adverse",
          "disclaimer"
        ]
      },
      "AccountsAuditorsReport": {
        "type": "object",
        "properties": {
          "text": {
            "type": "string",
            "description": "Word for word. Paragraphs separated by a blank line."
          },
          "opinion": {
            "allOf": [
              {
                "$ref": "#/components/schemas/AccountsAuditOpinion"
              }
            ]
          },
          "auditorName": {
            "type": "string",
            "description": "The auditor’s name, or the firm’s."
          },
          "seniorStatutoryAuditor": {
            "type": "string",
            "description": "Who signs for a firm (s503(3))."
          },
          "reportDate": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "address": {
            "type": "string",
            "description": "Where the auditor is established (s495(4)(d))."
          }
        },
        "description": "The auditor’s report, held as the auditor supplied it (CA 2006 ss495, 503). Tolvi doesn’t write or check it.",
        "required": [
          "text",
          "opinion",
          "auditorName",
          "reportDate",
          "address"
        ]
      },
      "AccountsPlFormat": {
        "type": "string",
        "enum": [
          "format1",
          "format2"
        ]
      },
      "AccountsComprehensiveIncomeLayout": {
        "type": "string",
        "enum": [
          "one_statement",
          "two_statements"
        ]
      },
      "AccountsStatementWording": {
        "type": "string",
        "enum": [
          "companies_act",
          "frs102"
        ]
      },
      "AccountsFullPresentation": {
        "type": "object",
        "properties": {
          "plFormat": {
            "allOf": [
              {
                "$ref": "#/components/schemas/AccountsPlFormat"
              }
            ]
          },
          "comprehensiveIncome": {
            "allOf": [
              {
                "$ref": "#/components/schemas/AccountsComprehensiveIncomeLayout"
              }
            ]
          },
          "combinedRetainedEarnings": {
            "type": "boolean"
          },
          "wording": {
            "allOf": [
              {
                "$ref": "#/components/schemas/AccountsStatementWording"
              }
            ]
          },
          "formatChangeReason": {
            "type": "string"
          }
        },
        "description": "How the statements are laid out. SI 2008/410 Sch 1 para 1; FRS 102 paras 3.18, 3.22, 5.2.",
        "required": [
          "plFormat",
          "comprehensiveIncome",
          "wording"
        ]
      },
      "AccountsCompanySize": {
        "type": "string",
        "enum": [
          "small",
          "medium",
          "large"
        ],
        "description": "How it qualified last year (CA 2006 s465(2)). Null for a first financial year."
      },
      "AccountsGroupBasis": {
        "type": "string",
        "enum": [
          "net",
          "gross"
        ]
      },
      "AccountsGroupFigures": {
        "type": "object",
        "properties": {
          "basis": {
            "allOf": [
              {
                "$ref": "#/components/schemas/AccountsGroupBasis"
              }
            ]
          },
          "turnover": {
            "type": "array",
            "items": {
              "type": "integer"
            },
            "minItems": 2,
            "maxItems": 2,
            "description": "[this year, last year], integer pence."
          },
          "balanceSheetTotal": {
            "type": "array",
            "items": {
              "type": "integer"
            },
            "minItems": 2,
            "maxItems": 2,
            "description": "[this year, last year], integer pence."
          },
          "employees": {
            "type": "array",
            "items": {
              "type": "integer",
              "minimum": 0
            },
            "minItems": 2,
            "maxItems": 2,
            "description": "[this year, last year], whole numbers."
          }
        },
        "description": "A parent’s size test (CA 2006 ss383, 466).",
        "required": [
          "basis",
          "turnover",
          "balanceSheetTotal",
          "employees"
        ]
      },
      "AccountsStrategicReport": {
        "type": "object",
        "properties": {
          "fairReview": {
            "type": "string"
          },
          "principalRisks": {
            "type": "string"
          },
          "financialKpis": {
            "type": [
              "string",
              "null"
            ]
          },
          "nonFinancialInformation": {
            "type": [
              "string",
              "null"
            ]
          },
          "section172Statement": {
            "type": "string"
          },
          "nonFinancialSustainabilityStatement": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "description": "CA 2006 ss414A to 414D. A person’s words."
      },
      "AccountsEmployeeCategory": {
        "type": "object",
        "properties": {
          "label": {
            "type": "string"
          },
          "values": {
            "type": "array",
            "items": {
              "type": "integer",
              "minimum": 0
            },
            "minItems": 2,
            "maxItems": 2,
            "description": "[this year, last year], whole numbers."
          }
        },
        "required": [
          "label",
          "values"
        ]
      },
      "AccountsStaffCosts": {
        "type": "object",
        "properties": {
          "wages": {
            "type": "array",
            "items": {
              "type": "integer"
            },
            "minItems": 2,
            "maxItems": 2,
            "description": "[this year, last year], integer pence."
          },
          "socialSecurity": {
            "type": "array",
            "items": {
              "type": "integer"
            },
            "minItems": 2,
            "maxItems": 2,
            "description": "[this year, last year], integer pence."
          },
          "pension": {
            "type": "array",
            "items": {
              "type": "integer"
            },
            "minItems": 2,
            "maxItems": 2,
            "description": "[this year, last year], integer pence."
          }
        },
        "description": "CA 2006 s411(5).",
        "required": [
          "wages",
          "socialSecurity",
          "pension"
        ]
      },
      "AccountsHighestPaidDirector": {
        "type": "object",
        "properties": {
          "remuneration": {
            "type": "array",
            "items": {
              "type": "integer"
            },
            "minItems": 2,
            "maxItems": 2,
            "description": "[this year, last year], integer pence."
          },
          "pensionContributions": {
            "type": "array",
            "items": {
              "type": "integer"
            },
            "minItems": 2,
            "maxItems": 2,
            "description": "[this year, last year], integer pence."
          },
          "accruedPension": {
            "type": "array",
            "items": {
              "type": "integer"
            },
            "minItems": 2,
            "maxItems": 2,
            "description": "[this year, last year], integer pence."
          },
          "accruedLumpSum": {
            "type": "array",
            "items": {
              "type": "integer"
            },
            "minItems": 2,
            "maxItems": 2,
            "description": "[this year, last year], integer pence."
          },
          "exercisedOptions": {
            "type": "boolean"
          },
          "receivedLongTermShares": {
            "type": "boolean"
          }
        },
        "description": "SI 2008/410 Sch 5 para 2.",
        "required": [
          "remuneration",
          "pensionContributions"
        ]
      },
      "AccountsAmountWithNature": {
        "type": "object",
        "properties": {
          "values": {
            "type": "array",
            "items": {
              "type": "integer"
            },
            "minItems": 2,
            "maxItems": 2,
            "description": "[this year, last year], integer pence."
          },
          "nature": {
            "type": "string"
          }
        },
        "required": [
          "values",
          "nature"
        ]
      },
      "AccountsDirectorsRemuneration": {
        "type": "object",
        "properties": {
          "remuneration": {
            "type": "array",
            "items": {
              "type": "integer"
            },
            "minItems": 2,
            "maxItems": 2,
            "description": "[this year, last year], integer pence."
          },
          "longTermIncentives": {
            "type": "array",
            "items": {
              "type": "integer"
            },
            "minItems": 2,
            "maxItems": 2,
            "description": "[this year, last year], integer pence."
          },
          "pensionContributions": {
            "type": "array",
            "items": {
              "type": "integer"
            },
            "minItems": 2,
            "maxItems": 2,
            "description": "[this year, last year], integer pence."
          },
          "moneyPurchaseDirectors": {
            "type": "array",
            "items": {
              "type": "integer",
              "minimum": 0
            },
            "minItems": 2,
            "maxItems": 2,
            "description": "[this year, last year], whole numbers."
          },
          "definedBenefitDirectors": {
            "type": "array",
            "items": {
              "type": "integer",
              "minimum": 0
            },
            "minItems": 2,
            "maxItems": 2,
            "description": "[this year, last year], whole numbers."
          },
          "exercisedOptionsDirectors": {
            "type": "array",
            "items": {
              "type": "integer",
              "minimum": 0
            },
            "minItems": 2,
            "maxItems": 2,
            "description": "[this year, last year], whole numbers."
          },
          "longTermSharesDirectors": {
            "type": "array",
            "items": {
              "type": "integer",
              "minimum": 0
            },
            "minItems": 2,
            "maxItems": 2,
            "description": "[this year, last year], whole numbers."
          },
          "highestPaid": {
            "$ref": "#/components/schemas/AccountsHighestPaidDirector"
          },
          "excessRetirementBenefits": {
            "type": "array",
            "items": {
              "type": "integer"
            },
            "minItems": 2,
            "maxItems": 2,
            "description": "[this year, last year], integer pence."
          },
          "lossOfOffice": {
            "$ref": "#/components/schemas/AccountsAmountWithNature"
          },
          "thirdParties": {
            "$ref": "#/components/schemas/AccountsAmountWithNature"
          }
        },
        "description": "SI 2008/410 Sch 5.",
        "required": [
          "remuneration",
          "longTermIncentives",
          "pensionContributions",
          "moneyPurchaseDirectors",
          "definedBenefitDirectors"
        ]
      },
      "AccountsTaxReconciliation": {
        "type": "object",
        "properties": {
          "rateBasisPoints": {
            "type": "array",
            "items": {
              "type": "integer",
              "minimum": 0
            },
            "minItems": 2,
            "maxItems": 2,
            "description": "Basis points, [this year, last year]."
          },
          "rateChangeExplanation": {
            "type": [
              "string",
              "null"
            ]
          },
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AccountsAnalysisRow"
            }
          }
        },
        "description": "FRS 102 para 29.27(b). The rate is in basis points: 25% is 2500.",
        "required": [
          "rateBasisPoints",
          "items"
        ]
      },
      "AccountsLandAndBuildings": {
        "type": "object",
        "properties": {
          "freehold": {
            "type": "array",
            "items": {
              "type": "integer"
            },
            "minItems": 2,
            "maxItems": 2,
            "description": "[this year, last year], integer pence."
          },
          "longLeasehold": {
            "type": "array",
            "items": {
              "type": "integer"
            },
            "minItems": 2,
            "maxItems": 2,
            "description": "[this year, last year], integer pence."
          },
          "shortLeasehold": {
            "type": "array",
            "items": {
              "type": "integer"
            },
            "minItems": 2,
            "maxItems": 2,
            "description": "[this year, last year], integer pence."
          }
        },
        "description": "SI 2008/410 Sch 1 para 53.",
        "required": [
          "freehold",
          "longLeasehold",
          "shortLeasehold"
        ]
      },
      "AccountsListedInvestments": {
        "type": "object",
        "properties": {
          "carrying": {
            "type": "array",
            "items": {
              "type": "integer"
            },
            "minItems": 2,
            "maxItems": 2,
            "description": "[this year, last year], integer pence."
          },
          "marketValue": {
            "type": "array",
            "items": {
              "type": "integer"
            },
            "minItems": 2,
            "maxItems": 2,
            "description": "[this year, last year], integer pence."
          }
        },
        "description": "SI 2008/410 Sch 1 para 54.",
        "required": [
          "carrying",
          "marketValue"
        ]
      },
      "AccountsLeases": {
        "type": "object",
        "properties": {
          "description": {
            "type": "string"
          },
          "shortTermExpense": {
            "type": "array",
            "items": {
              "type": "integer"
            },
            "minItems": 2,
            "maxItems": 2,
            "description": "[this year, last year], integer pence."
          },
          "lowValueExpense": {
            "type": "array",
            "items": {
              "type": "integer"
            },
            "minItems": 2,
            "maxItems": 2,
            "description": "[this year, last year], integer pence."
          },
          "variableExpense": {
            "type": "array",
            "items": {
              "type": "integer"
            },
            "minItems": 2,
            "maxItems": 2,
            "description": "[this year, last year], integer pence."
          },
          "interestExpense": {
            "type": "array",
            "items": {
              "type": "integer"
            },
            "minItems": 2,
            "maxItems": 2,
            "description": "[this year, last year], integer pence."
          },
          "subleaseIncome": {
            "type": "array",
            "items": {
              "type": "integer"
            },
            "minItems": 2,
            "maxItems": 2,
            "description": "[this year, last year], integer pence."
          },
          "totalCashOutflow": {
            "type": "array",
            "items": {
              "type": "integer"
            },
            "minItems": 2,
            "maxItems": 2,
            "description": "[this year, last year], integer pence."
          },
          "commitmentsWithinOneYear": {
            "type": "array",
            "items": {
              "type": "integer"
            },
            "minItems": 2,
            "maxItems": 2,
            "description": "[this year, last year], integer pence."
          },
          "commitmentsOneToFiveYears": {
            "type": "array",
            "items": {
              "type": "integer"
            },
            "minItems": 2,
            "maxItems": 2,
            "description": "[this year, last year], integer pence."
          },
          "commitmentsAfterFiveYears": {
            "type": "array",
            "items": {
              "type": "integer"
            },
            "minItems": 2,
            "maxItems": 2,
            "description": "[this year, last year], integer pence."
          }
        },
        "description": "FRS 102 paras 20.76 to 20.82.",
        "required": [
          "description"
        ]
      },
      "AccountsPensions": {
        "type": "object",
        "properties": {
          "definedContributionExpense": {
            "type": "array",
            "items": {
              "type": "integer"
            },
            "minItems": 2,
            "maxItems": 2,
            "description": "[this year, last year], integer pence."
          },
          "definedBenefit": {
            "type": "string"
          }
        },
        "description": "FRS 102 paras 28.40, 28.41.",
        "required": [
          "definedContributionExpense"
        ]
      },
      "AccountsControllingParty": {
        "type": "object",
        "properties": {
          "immediateParent": {
            "type": "string"
          },
          "ultimateParent": {
            "type": "string"
          },
          "ultimateControllingParty": {
            "type": "string"
          },
          "nextSeniorParent": {
            "type": "string"
          },
          "largestGroup": {
            "type": "string"
          },
          "smallestGroup": {
            "type": "string"
          }
        },
        "description": "FRS 102 para 33.5; SI 2008/410 Sch 4 paras 8, 9."
      },
      "AccountsUndertakingRelationship": {
        "type": "string",
        "enum": [
          "subsidiary",
          "associate",
          "joint_venture",
          "significant_holding"
        ]
      },
      "AccountsRelatedUndertaking": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string"
          },
          "registeredOffice": {
            "type": "string"
          },
          "relationship": {
            "allOf": [
              {
                "$ref": "#/components/schemas/AccountsUndertakingRelationship"
              }
            ]
          },
          "shareClass": {
            "type": "string"
          },
          "proportionHeld": {
            "type": "string"
          },
          "capitalAndReserves": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "profitOrLoss": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          }
        },
        "description": "SI 2008/410 Sch 4.",
        "required": [
          "name",
          "registeredOffice",
          "relationship",
          "shareClass",
          "proportionHeld"
        ]
      },
      "AccountsReducedDisclosure": {
        "type": "object",
        "properties": {
          "parentName": {
            "type": "string"
          },
          "whereObtainable": {
            "type": "string"
          },
          "cashFlowExempt": {
            "type": "boolean"
          },
          "financialInstrumentsExempt": {
            "type": "boolean"
          },
          "keyManagementExempt": {
            "type": "boolean"
          },
          "financialInstitution": {
            "type": "boolean"
          },
          "summary": {
            "type": "string"
          }
        },
        "description": "FRS 102 paras 1.8 to 1.12.",
        "required": [
          "parentName",
          "whereObtainable",
          "cashFlowExempt"
        ]
      },
      "AccountsFullFacts": {
        "type": "object",
        "properties": {
          "presentation": {
            "$ref": "#/components/schemas/AccountsFullPresentation"
          },
          "qualifiedLastYear": {
            "description": "How it qualified last year (CA 2006 s465(2)). Null for a first financial year.",
            "oneOf": [
              {
                "$ref": "#/components/schemas/AccountsCompanySize"
              },
              {
                "type": "null"
              }
            ]
          },
          "groupFigures": {
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/AccountsGroupFigures"
              }
            ]
          },
          "groupAccountsExemption": {
            "type": "string"
          },
          "strategicReport": {
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/AccountsStrategicReport"
              }
            ]
          },
          "recommendedDividend": {
            "type": [
              "string",
              "null"
            ]
          },
          "movedToStrategicReport": {
            "type": [
              "string",
              "null"
            ]
          },
          "energyAndCarbon": {
            "type": [
              "string",
              "null"
            ]
          },
          "corporateGovernance": {
            "type": [
              "string",
              "null"
            ]
          },
          "paymentPractices": {
            "type": [
              "string",
              "null"
            ]
          },
          "earlierDirectorsReportMatters": {
            "type": [
              "string",
              "null"
            ]
          },
          "judgements": {
            "type": [
              "string",
              "null"
            ]
          },
          "estimationUncertainty": {
            "type": [
              "string",
              "null"
            ]
          },
          "furtherPolicies": {
            "type": [
              "string",
              "null"
            ]
          },
          "auditorRemuneration": {
            "type": "array",
            "items": {
              "type": "integer"
            },
            "minItems": 2,
            "maxItems": 2,
            "description": "[this year, last year], integer pence."
          },
          "employeeCategories": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AccountsEmployeeCategory"
            }
          },
          "staffCosts": {
            "$ref": "#/components/schemas/AccountsStaffCosts"
          },
          "directorsRemuneration": {
            "$ref": "#/components/schemas/AccountsDirectorsRemuneration"
          },
          "keyManagementCompensation": {
            "type": [
              "array",
              "null"
            ],
            "items": {
              "type": "integer"
            },
            "minItems": 2,
            "maxItems": 2,
            "description": "[this year, last year], integer pence."
          },
          "taxReconciliation": {
            "$ref": "#/components/schemas/AccountsTaxReconciliation"
          },
          "taxSpecialCircumstances": {
            "type": [
              "string",
              "null"
            ]
          },
          "deferredTaxExpectedReversal": {
            "type": [
              "string",
              "null"
            ]
          },
          "deferredTaxOther": {
            "type": [
              "string",
              "null"
            ]
          },
          "dividendsProposed": {
            "type": [
              "array",
              "null"
            ],
            "items": {
              "type": "integer"
            },
            "minItems": 2,
            "maxItems": 2,
            "description": "[this year, last year], integer pence."
          },
          "valuations": {
            "type": [
              "string",
              "null"
            ]
          },
          "materialIntangibles": {
            "type": [
              "string",
              "null"
            ]
          },
          "researchAndDevelopment": {
            "type": [
              "array",
              "null"
            ],
            "items": {
              "type": "integer"
            },
            "minItems": 2,
            "maxItems": 2,
            "description": "[this year, last year], integer pence."
          },
          "capitalCommitments": {
            "type": [
              "array",
              "null"
            ],
            "items": {
              "type": "integer"
            },
            "minItems": 2,
            "maxItems": 2,
            "description": "[this year, last year], integer pence."
          },
          "assetsPledged": {
            "type": [
              "string",
              "null"
            ]
          },
          "stocksInformation": {
            "type": [
              "string",
              "null"
            ]
          },
          "debtorsAfterOneYear": {
            "type": [
              "array",
              "null"
            ],
            "items": {
              "type": "integer"
            },
            "minItems": 2,
            "maxItems": 2,
            "description": "[this year, last year], integer pence."
          },
          "longTermDebtTerms": {
            "type": [
              "string",
              "null"
            ]
          },
          "financialInstruments": {
            "type": [
              "string",
              "null"
            ]
          },
          "shareRights": {
            "type": "string"
          },
          "landAndBuildings": {
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/AccountsLandAndBuildings"
              }
            ]
          },
          "listedInvestments": {
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/AccountsListedInvestments"
              }
            ]
          },
          "leases": {
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/AccountsLeases"
              }
            ]
          },
          "pensions": {
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/AccountsPensions"
              }
            ]
          },
          "contingencies": {
            "type": [
              "string",
              "null"
            ]
          },
          "controllingParty": {
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/AccountsControllingParty"
              }
            ]
          },
          "relatedUndertakings": {
            "type": [
              "array",
              "null"
            ],
            "items": {
              "$ref": "#/components/schemas/AccountsRelatedUndertaking"
            }
          },
          "reducedDisclosure": {
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/AccountsReducedDisclosure"
              }
            ]
          },
          "sorp": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "description": "What only full FRS 102 asks. Left out is unanswered, null is none."
      },
      "AccountsMembersMovementKind": {
        "type": "string",
        "enum": [
          "introduced",
          "repaid_capital",
          "repaid_debt",
          "drawings",
          "other_division",
          "other"
        ]
      },
      "AccountsMembersInterest": {
        "type": "string",
        "enum": [
          "capital",
          "capital_debt",
          "other_reserves",
          "revaluation",
          "other_amounts"
        ]
      },
      "AccountsMembersMovement": {
        "type": "object",
        "properties": {
          "label": {
            "type": "string"
          },
          "kind": {
            "allOf": [
              {
                "$ref": "#/components/schemas/AccountsMembersMovementKind"
              }
            ]
          },
          "component": {
            "allOf": [
              {
                "$ref": "#/components/schemas/AccountsMembersInterest"
              }
            ]
          },
          "values": {
            "type": "array",
            "items": {
              "type": "integer"
            },
            "minItems": 2,
            "maxItems": 2,
            "description": "[this year, last year], integer pence."
          }
        },
        "description": "One movement in members’ interests (LLP SORP 2026 para 60). Positive adds to the balance.",
        "required": [
          "label",
          "kind",
          "component",
          "values"
        ]
      },
      "AccountsLlpFacts": {
        "type": "object",
        "properties": {
          "remunerationPolicy": {
            "type": "string"
          },
          "drawingsPolicy": {
            "type": "string"
          },
          "rankingAndRestrictions": {
            "type": "string"
          },
          "movements": {
            "type": [
              "array",
              "null"
            ],
            "items": {
              "$ref": "#/components/schemas/AccountsMembersMovement"
            }
          },
          "debtsDueAfterOneYear": {
            "type": [
              "array",
              "null"
            ],
            "items": {
              "type": "integer"
            },
            "minItems": 2,
            "maxItems": 2,
            "description": "[this year, last year], integer pence."
          },
          "averageMembers": {
            "description": "SI 2008/1913 Sch 1 para 66(1), (2).",
            "allOf": [
              {
                "$ref": "#/components/schemas/AccountsEmployees"
              }
            ]
          },
          "largestEntitlement": {
            "type": [
              "array",
              "null"
            ],
            "items": {
              "type": "integer"
            },
            "minItems": 2,
            "maxItems": 2,
            "description": "[this year, last year], integer pence."
          },
          "largestEntitlementPolicy": {
            "type": "string"
          }
        },
        "description": "What an LLP’s accounts ask, under SI 2008/1911, 1912 and 1913 and the LLP SORP 2026."
      },
      "AccountsAccountantsReport": {
        "type": "object",
        "properties": {
          "text": {
            "type": "string"
          },
          "firmName": {
            "type": "string"
          },
          "address": {
            "type": "string"
          },
          "reportDate": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          }
        },
        "description": "The firm’s own words, as supplied. Tolvi prints them and has none of its own.",
        "required": [
          "text",
          "firmName"
        ]
      },
      "AccountsPartner": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string"
          },
          "shareWeight": {
            "type": "integer",
            "minimum": 0,
            "description": "Profit-sharing weight, such as 50, 30, 20."
          },
          "salary": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "interestOnCapital": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "capitalOpening": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "capitalIntroduced": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "capitalWithdrawn": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "currentOpening": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "drawings": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          }
        },
        "description": "One partner’s accounts and profit share. Amounts in integer pence.",
        "required": [
          "name",
          "shareWeight",
          "capitalOpening",
          "currentOpening",
          "drawings"
        ]
      },
      "AccountsNonStatutoryFacts": {
        "type": "object",
        "properties": {
          "accountantsReport": {
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/AccountsAccountantsReport"
              }
            ]
          },
          "capitalIntroduced": {
            "type": "array",
            "items": {
              "type": "integer"
            },
            "minItems": 2,
            "maxItems": 2,
            "description": "[this year, last year], integer pence."
          },
          "partners": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AccountsPartner"
            }
          },
          "qualifyingPartnership": {
            "type": "boolean",
            "description": "SI 2008/569. A blocker: that form isn’t built."
          }
        },
        "description": "What a sole trader’s or partnership’s accounts ask."
      },
      "AccountsCharityForm": {
        "type": "string",
        "enum": [
          "unincorporated",
          "trust",
          "cio",
          "scio",
          "charitable_company"
        ]
      },
      "AccountsCharityJurisdiction": {
        "type": "string",
        "enum": [
          "england_wales",
          "scotland",
          "northern_ireland"
        ]
      },
      "AccountsCharityPresentation": {
        "type": "string",
        "enum": [
          "activity",
          "natural"
        ],
        "description": "Natural classification is for tier 1 only (SORP para 4.2)."
      },
      "AccountsFundClass": {
        "type": "string",
        "enum": [
          "unrestricted",
          "designated",
          "restricted",
          "endowment"
        ]
      },
      "AccountsEndowmentKind": {
        "type": "string",
        "enum": [
          "permanent",
          "expendable"
        ]
      },
      "AccountsCharityFund": {
        "type": "object",
        "properties": {
          "fundClass": {
            "allOf": [
              {
                "$ref": "#/components/schemas/AccountsFundClass"
              }
            ]
          },
          "name": {
            "type": "string"
          },
          "purpose": {
            "type": "string"
          },
          "endowmentKind": {
            "allOf": [
              {
                "$ref": "#/components/schemas/AccountsEndowmentKind"
              }
            ]
          },
          "legalPower": {
            "type": "string"
          }
        },
        "description": "One fund in the register (SORP paras 2.34, 2.35).",
        "required": [
          "fundClass",
          "name"
        ]
      },
      "AccountsCharityLineMapping": {
        "type": "object",
        "properties": {
          "account": {
            "type": "string"
          },
          "statementLine": {
            "type": "string"
          },
          "fundClass": {
            "allOf": [
              {
                "$ref": "#/components/schemas/AccountsFundClass"
              }
            ]
          },
          "fundName": {
            "type": "string"
          }
        },
        "description": "For a trial balance that can’t say, such as a linked file: which statement line and fund an account belongs to, by its name.",
        "required": [
          "account"
        ]
      },
      "AccountsExaminersReport": {
        "type": "object",
        "properties": {
          "text": {
            "type": "string"
          },
          "examinerName": {
            "type": "string"
          },
          "address": {
            "type": "string"
          },
          "qualification": {
            "type": "string"
          },
          "qualifyingBasis": {
            "type": "string"
          },
          "reportDate": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          }
        },
        "description": "The examiner’s own report, as supplied, with what the regulations say it states. Tolvi doesn’t write it.",
        "required": [
          "text",
          "examinerName",
          "address",
          "reportDate"
        ]
      },
      "AccountsCharityStaffCosts": {
        "type": "object",
        "properties": {
          "wages": {
            "type": "array",
            "items": {
              "type": "integer"
            },
            "minItems": 2,
            "maxItems": 2,
            "description": "[this year, last year], integer pence."
          },
          "socialSecurity": {
            "type": "array",
            "items": {
              "type": "integer"
            },
            "minItems": 2,
            "maxItems": 2,
            "description": "[this year, last year], integer pence."
          },
          "definedContribution": {
            "type": "array",
            "items": {
              "type": "integer"
            },
            "minItems": 2,
            "maxItems": 2,
            "description": "[this year, last year], integer pence."
          },
          "definedBenefit": {
            "type": "array",
            "items": {
              "type": "integer"
            },
            "minItems": 2,
            "maxItems": 2,
            "description": "[this year, last year], integer pence."
          },
          "otherBenefits": {
            "type": "array",
            "items": {
              "type": "integer"
            },
            "minItems": 2,
            "maxItems": 2,
            "description": "[this year, last year], integer pence."
          }
        },
        "description": "SORP para 9.28.",
        "required": [
          "wages",
          "socialSecurity",
          "definedContribution"
        ]
      },
      "AccountsCharityRedundancy": {
        "type": "object",
        "properties": {
          "total": {
            "type": "array",
            "items": {
              "type": "integer"
            },
            "minItems": 2,
            "maxItems": 2,
            "description": "[this year, last year], integer pence."
          },
          "nature": {
            "type": "string"
          },
          "policy": {
            "type": "string"
          },
          "liability": {
            "type": "array",
            "items": {
              "type": "integer"
            },
            "minItems": 2,
            "maxItems": 2,
            "description": "[this year, last year], integer pence."
          }
        },
        "description": "SORP para 9.31.",
        "required": [
          "total",
          "nature",
          "policy",
          "liability"
        ]
      },
      "AccountsCharityPayBand": {
        "type": "object",
        "properties": {
          "label": {
            "type": "string"
          },
          "values": {
            "type": "array",
            "items": {
              "type": "number"
            }
          }
        },
        "description": "SORP para 9.34. `values`: [this year, last year], how many people.",
        "required": [
          "label",
          "values"
        ]
      },
      "AccountsTrusteeRemuneration": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string"
          },
          "role": {
            "type": "string"
          },
          "authority": {
            "type": "string"
          },
          "reason": {
            "type": "string"
          },
          "remuneration": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "pension": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "otherBenefits": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "periodCovered": {
            "type": "string"
          }
        },
        "description": "SORP para 9.7.",
        "required": [
          "name",
          "role",
          "authority",
          "reason",
          "remuneration",
          "pension",
          "otherBenefits"
        ]
      },
      "AccountsCharityTrusteeExpenses": {
        "type": "object",
        "properties": {
          "total": {
            "type": "array",
            "items": {
              "type": "integer"
            },
            "minItems": 2,
            "maxItems": 2,
            "description": "[this year, last year], integer pence."
          },
          "nature": {
            "type": "string"
          },
          "trustees": {
            "type": "array",
            "items": {
              "type": "number"
            }
          }
        },
        "description": "SORP paras 9.11, 9.12. `trustees`: [this year, last year].",
        "required": [
          "total",
          "nature",
          "trustees"
        ]
      },
      "AccountsCharityScrutinyFees": {
        "type": "object",
        "properties": {
          "scrutiny": {
            "type": "array",
            "items": {
              "type": "integer"
            },
            "minItems": 2,
            "maxItems": 2,
            "description": "[this year, last year], integer pence."
          },
          "assurance": {
            "type": "array",
            "items": {
              "type": "integer"
            },
            "minItems": 2,
            "maxItems": 2,
            "description": "[this year, last year], integer pence."
          },
          "tax": {
            "type": "array",
            "items": {
              "type": "integer"
            },
            "minItems": 2,
            "maxItems": 2,
            "description": "[this year, last year], integer pence."
          },
          "other": {
            "type": "array",
            "items": {
              "type": "integer"
            },
            "minItems": 2,
            "maxItems": 2,
            "description": "[this year, last year], integer pence."
          }
        },
        "description": "SORP para 9.25.",
        "required": [
          "scrutiny"
        ]
      },
      "AccountsCharityGrants": {
        "type": "object",
        "properties": {
          "individuals": {
            "type": "array",
            "items": {
              "type": "integer"
            },
            "minItems": 2,
            "maxItems": 2,
            "description": "[this year, last year], integer pence."
          },
          "institutions": {
            "type": "array",
            "items": {
              "type": "integer"
            },
            "minItems": 2,
            "maxItems": 2,
            "description": "[this year, last year], integer pence."
          },
          "supportCosts": {
            "type": "array",
            "items": {
              "type": "integer"
            },
            "minItems": 2,
            "maxItems": 2,
            "description": "[this year, last year], integer pence."
          },
          "byActivity": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AccountsAnalysisRow"
            }
          },
          "recipients": {
            "type": "string"
          }
        },
        "description": "SORP paras 16.14 to 16.16.",
        "required": [
          "individuals",
          "institutions"
        ]
      },
      "AccountsReceiptsPaymentsFacts": {
        "type": "object",
        "properties": {
          "otherMonetaryAssets": {
            "type": [
              "array",
              "null"
            ],
            "items": {
              "$ref": "#/components/schemas/AccountsAnalysisRow"
            }
          },
          "investments": {
            "type": [
              "array",
              "null"
            ],
            "items": {
              "$ref": "#/components/schemas/AccountsAnalysisRow"
            }
          },
          "ownUseAssets": {
            "type": [
              "array",
              "null"
            ],
            "items": {
              "$ref": "#/components/schemas/AccountsAnalysisRow"
            }
          },
          "liabilities": {
            "type": [
              "array",
              "null"
            ],
            "items": {
              "$ref": "#/components/schemas/AccountsAnalysisRow"
            }
          },
          "contingentLiabilities": {
            "type": [
              "string",
              "null"
            ]
          },
          "guarantees": {
            "type": [
              "string",
              "null"
            ]
          },
          "chargedDebts": {
            "type": [
              "string",
              "null"
            ]
          },
          "donatedFacilities": {
            "type": [
              "string",
              "null"
            ]
          },
          "grantsPaid": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "description": "What a cash account can’t say: SSI 2006/218 Sch 3, and the Commission’s guidance for CIOs. Null: none."
      },
      "AccountsCharityFacts": {
        "type": "object",
        "properties": {
          "form": {
            "allOf": [
              {
                "$ref": "#/components/schemas/AccountsCharityForm"
              }
            ]
          },
          "jurisdiction": {
            "allOf": [
              {
                "$ref": "#/components/schemas/AccountsCharityJurisdiction"
              }
            ]
          },
          "alsoRegisteredIn": {
            "description": "A cross-border charity’s other regulators.",
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "charityNumber": {
            "type": [
              "string",
              "null"
            ]
          },
          "otherCharityNumbers": {
            "type": "string"
          },
          "report": {
            "type": "object",
            "additionalProperties": {
              "type": [
                "string",
                "null"
              ]
            },
            "description": "Answers for the trustees’ annual report, by the question ids in `charity.questions`."
          },
          "presentation": {
            "description": "Natural classification is for tier 1 only (SORP para 4.2).",
            "allOf": [
              {
                "$ref": "#/components/schemas/AccountsCharityPresentation"
              }
            ]
          },
          "funds": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AccountsCharityFund"
            }
          },
          "lineMap": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AccountsCharityLineMapping"
            }
          },
          "auditRequiredOtherwise": {
            "type": "boolean"
          },
          "scrutinyDispensation": {
            "type": [
              "string",
              "null"
            ]
          },
          "examinersReport": {
            "$ref": "#/components/schemas/AccountsExaminersReport"
          },
          "isParent": {
            "type": "boolean"
          },
          "groupGrossIncome": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "averageHeadcount": {
            "$ref": "#/components/schemas/AccountsEmployees"
          },
          "staffCosts": {
            "$ref": "#/components/schemas/AccountsCharityStaffCosts"
          },
          "redundancy": {
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/AccountsCharityRedundancy"
              }
            ]
          },
          "highPaidBands": {
            "type": [
              "array",
              "null"
            ],
            "items": {
              "$ref": "#/components/schemas/AccountsCharityPayBand"
            }
          },
          "trusteeRemuneration": {
            "type": [
              "array",
              "null"
            ],
            "items": {
              "$ref": "#/components/schemas/AccountsTrusteeRemuneration"
            }
          },
          "trusteeExpenses": {
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/AccountsCharityTrusteeExpenses"
              }
            ]
          },
          "keyManagementBenefits": {
            "type": "array",
            "items": {
              "type": "integer"
            },
            "minItems": 2,
            "maxItems": 2,
            "description": "[this year, last year], integer pence."
          },
          "relatedPartyDonations": {
            "type": [
              "array",
              "null"
            ],
            "items": {
              "type": "integer"
            },
            "minItems": 2,
            "maxItems": 2,
            "description": "[this year, last year], integer pence."
          },
          "scrutinyFees": {
            "$ref": "#/components/schemas/AccountsCharityScrutinyFees"
          },
          "exGratia": {
            "type": [
              "string",
              "null"
            ]
          },
          "grants": {
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/AccountsCharityGrants"
              }
            ]
          },
          "judgements": {
            "type": [
              "string",
              "null"
            ]
          },
          "furtherPolicies": {
            "type": [
              "string",
              "null"
            ]
          },
          "reservesNotFree": {
            "type": [
              "array",
              "null"
            ],
            "items": {
              "$ref": "#/components/schemas/AccountsAnalysisRow"
            }
          },
          "revaluationReserve": {
            "type": [
              "array",
              "null"
            ],
            "items": {
              "type": "integer"
            },
            "minItems": 2,
            "maxItems": 2,
            "description": "[this year, last year], integer pence."
          },
          "receiptsAndPayments": {
            "$ref": "#/components/schemas/AccountsReceiptsPaymentsFacts"
          }
        },
        "description": "What a charity’s accounts ask. Left out: not answered. Null: none. Narrative is a person’s words."
      },
      "AccountsInputs": {
        "type": "object",
        "properties": {
          "averageEmployees": {
            "$ref": "#/components/schemas/AccountsEmployees"
          },
          "offBalanceSheetArrangements": {
            "type": [
              "string",
              "null"
            ]
          },
          "commitments": {
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/AccountsCommitments"
              }
            ]
          },
          "directorAdvances": {
            "type": [
              "array",
              "null"
            ],
            "items": {
              "$ref": "#/components/schemas/AccountsDirectorAdvance"
            }
          },
          "directorGuarantees": {
            "type": [
              "array",
              "null"
            ],
            "items": {
              "$ref": "#/components/schemas/AccountsDirectorGuarantee"
            }
          },
          "relatedParties": {
            "type": [
              "string",
              "null"
            ]
          },
          "parentUndertaking": {
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/AccountsParentUndertaking"
              }
            ]
          },
          "postBalanceSheetEvents": {
            "type": [
              "string",
              "null"
            ]
          },
          "goingConcern": {
            "$ref": "#/components/schemas/AccountsGoingConcern"
          },
          "dividends": {
            "type": [
              "array",
              "null"
            ],
            "items": {
              "type": "integer"
            },
            "minItems": 2,
            "maxItems": 2,
            "description": "[this year, last year], integer pence."
          },
          "shareCapital": {
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/AccountsShareCapital"
              }
            ]
          },
          "exceptionalItems": {
            "type": [
              "array",
              "null"
            ],
            "items": {
              "$ref": "#/components/schemas/AccountsExceptionalItem"
            }
          },
          "transitionExplanation": {
            "type": [
              "string",
              "null"
            ]
          },
          "depreciationPolicy": {
            "type": "string"
          },
          "politicalGiving": {
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/AccountsPoliticalGiving"
              }
            ]
          },
          "auditExemption": {
            "$ref": "#/components/schemas/AccountsAuditExemption"
          },
          "approval": {
            "$ref": "#/components/schemas/AccountsProposedSignatory"
          },
          "exclusions": {
            "$ref": "#/components/schemas/AccountsExclusions"
          },
          "revaluedFixedAssets": {
            "type": "boolean"
          },
          "fairValueItems": {
            "type": "boolean"
          },
          "deferredTaxInFigures": {
            "type": "boolean"
          },
          "expectedFilingDate": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31",
            "description": "When the accounts are expected to reach Companies House, for dated warnings. Tolvi does not file them."
          },
          "auditorsReport": {
            "description": "Needed where the s477 exemption isn’t taken.",
            "allOf": [
              {
                "$ref": "#/components/schemas/AccountsAuditorsReport"
              }
            ]
          },
          "full": {
            "description": "FRS102_FULL only.",
            "allOf": [
              {
                "$ref": "#/components/schemas/AccountsFullFacts"
              }
            ]
          },
          "llp": {
            "description": "An LLP only.",
            "allOf": [
              {
                "$ref": "#/components/schemas/AccountsLlpFacts"
              }
            ]
          },
          "nonStatutory": {
            "description": "A sole trader or partnership only.",
            "allOf": [
              {
                "$ref": "#/components/schemas/AccountsNonStatutoryFacts"
              }
            ]
          },
          "charity": {
            "description": "A charity only.",
            "allOf": [
              {
                "$ref": "#/components/schemas/AccountsCharityFacts"
              }
            ]
          }
        },
        "description": "Facts for the notes and statements. Left out means not answered, so a problem asks for it where it is needed. Null means answered, nothing to disclose: the note drops out and later notes renumber."
      },
      "AccountsFixedAssetKind": {
        "type": "string",
        "enum": [
          "intangible",
          "tangible",
          "investment"
        ]
      },
      "AccountsFixedAssetClass": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string"
          },
          "kind": {
            "allOf": [
              {
                "$ref": "#/components/schemas/AccountsFixedAssetKind"
              }
            ]
          },
          "costOpening": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "additions": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "disposals": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "revaluation": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "transfers": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "costClosing": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "depreciationOpening": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "chargeForYear": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "onDisposals": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "otherAdjustments": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "depreciationClosing": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          }
        },
        "description": "One class in the movement table (SI 2008/409 Sch 1 para 48).",
        "required": [
          "name",
          "costOpening",
          "additions",
          "disposals",
          "costClosing",
          "depreciationOpening",
          "chargeForYear",
          "onDisposals",
          "depreciationClosing"
        ]
      },
      "AccountsSecuredItem": {
        "type": "string",
        "enum": [
          "within_one_year",
          "after_one_year"
        ]
      },
      "AccountsSecuredCreditors": {
        "type": "object",
        "properties": {
          "item": {
            "allOf": [
              {
                "$ref": "#/components/schemas/AccountsSecuredItem"
              }
            ]
          },
          "values": {
            "type": "array",
            "items": {
              "type": "integer"
            },
            "minItems": 2,
            "maxItems": 2,
            "description": "[this year, last year], integer pence."
          },
          "security": {
            "type": "string"
          }
        },
        "required": [
          "item",
          "values",
          "security"
        ]
      },
      "AccountsReclassification": {
        "type": "object",
        "properties": {
          "label": {
            "type": "string"
          },
          "from": {
            "type": "string",
            "description": "A statement line id."
          },
          "to": {
            "type": "string",
            "description": "A statement line id."
          },
          "values": {
            "type": "array",
            "items": {
              "type": "integer"
            },
            "minItems": 2,
            "maxItems": 2,
            "description": "[this year, last year], integer pence."
          }
        },
        "description": "Moves an amount between statement lines, so a Working Papers file’s lines can show what its mapping can’t. Signed like the trial balance: debit positive.",
        "required": [
          "label",
          "from",
          "to",
          "values"
        ]
      },
      "AccountsEquityMovementKind": {
        "type": "string",
        "enum": [
          "share_issue",
          "share_purchase",
          "transfer",
          "restatement",
          "other"
        ]
      },
      "AccountsEquityComponent": {
        "type": "string",
        "enum": [
          "share_capital",
          "share_premium",
          "revaluation_reserve",
          "other_reserves",
          "retained_earnings"
        ]
      },
      "AccountsEquityMovement": {
        "type": "object",
        "properties": {
          "label": {
            "type": "string"
          },
          "kind": {
            "allOf": [
              {
                "$ref": "#/components/schemas/AccountsEquityMovementKind"
              }
            ]
          },
          "component": {
            "allOf": [
              {
                "$ref": "#/components/schemas/AccountsEquityComponent"
              }
            ]
          },
          "values": {
            "type": "array",
            "items": {
              "type": "integer"
            },
            "minItems": 2,
            "maxItems": 2,
            "description": "[this year, last year], integer pence."
          }
        },
        "description": "A movement in equity other than profit, other comprehensive income or dividends (FRS 102 para 6.3).",
        "required": [
          "label",
          "kind",
          "component",
          "values"
        ]
      },
      "AccountsInterestPaidClass": {
        "type": "string",
        "enum": [
          "operating",
          "financing"
        ]
      },
      "AccountsInterestReceivedClass": {
        "type": "string",
        "enum": [
          "operating",
          "investing"
        ]
      },
      "AccountsDividendsPaidClass": {
        "type": "string",
        "enum": [
          "financing",
          "operating"
        ]
      },
      "AccountsRestrictedCash": {
        "type": "object",
        "properties": {
          "amount": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "commentary": {
            "type": "string"
          }
        },
        "description": "FRS 102 para 7.21.",
        "required": [
          "amount",
          "commentary"
        ]
      },
      "AccountsCashFlowFacts": {
        "type": "object",
        "properties": {
          "overdraftsAreCash": {
            "type": "boolean"
          },
          "cashEquivalents": {
            "type": [
              "array",
              "null"
            ],
            "items": {
              "type": "integer"
            },
            "minItems": 2,
            "maxItems": 2,
            "description": "[this year, last year], integer pence."
          },
          "interestPaid": {
            "allOf": [
              {
                "$ref": "#/components/schemas/AccountsInterestPaidClass"
              }
            ]
          },
          "interestReceived": {
            "allOf": [
              {
                "$ref": "#/components/schemas/AccountsInterestReceivedClass"
              }
            ]
          },
          "dividendsPaid": {
            "allOf": [
              {
                "$ref": "#/components/schemas/AccountsDividendsPaidClass"
              }
            ]
          },
          "capitalCreditors": {
            "type": "array",
            "items": {
              "type": "integer"
            },
            "minItems": 2,
            "maxItems": 2,
            "description": "[this year, last year], integer pence."
          },
          "dividendsPayable": {
            "type": "array",
            "items": {
              "type": "integer"
            },
            "minItems": 2,
            "maxItems": 2,
            "description": "[this year, last year], integer pence."
          },
          "interestPayable": {
            "type": "array",
            "items": {
              "type": "integer"
            },
            "minItems": 2,
            "maxItems": 2,
            "description": "[this year, last year], integer pence."
          },
          "interestReceivable": {
            "type": "array",
            "items": {
              "type": "integer"
            },
            "minItems": 2,
            "maxItems": 2,
            "description": "[this year, last year], integer pence."
          },
          "newLeases": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "borrowingsDrawn": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "borrowingsRepaid": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "exchangeOnCash": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "debtNonCash": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "debtMarketAndExchange": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "restrictedCash": {
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/AccountsRestrictedCash"
              }
            ]
          },
          "nonCashTransactions": {
            "type": [
              "string",
              "null"
            ]
          },
          "comparatives": {
            "type": "object",
            "additionalProperties": {
              "type": "integer"
            },
            "description": "Last year’s statement of cash flows, by row key, integer pence. Rolls from last year’s set."
          },
          "priorOpeningCash": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          }
        },
        "description": "What two balance sheets can’t say (FRS 102 Section 7). Closing balances are positive, whether they sit in creditors or debtors."
      },
      "AccountsPriorCharges": {
        "type": "object",
        "properties": {
          "amortisation": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "depreciation": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          }
        },
        "description": "Last year’s amortisation and depreciation, for the comparative in the operating profit note.",
        "required": [
          "amortisation",
          "depreciation"
        ]
      },
      "AccountsProvisionMovement": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string"
          },
          "nature": {
            "type": "string"
          },
          "opening": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "additions": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "charged": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "reversed": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "closing": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          }
        },
        "description": "FRS 102 para 21.14.",
        "required": [
          "name",
          "nature",
          "opening",
          "additions",
          "charged",
          "reversed",
          "closing"
        ]
      },
      "AccountsFullAnalyses": {
        "type": "object",
        "properties": {
          "reclassifications": {
            "type": [
              "array",
              "null"
            ],
            "items": {
              "$ref": "#/components/schemas/AccountsReclassification"
            }
          },
          "equityMovements": {
            "type": [
              "array",
              "null"
            ],
            "items": {
              "$ref": "#/components/schemas/AccountsEquityMovement"
            }
          },
          "cashFlow": {
            "$ref": "#/components/schemas/AccountsCashFlowFacts"
          },
          "turnoverByClass": {
            "type": [
              "array",
              "null"
            ],
            "items": {
              "$ref": "#/components/schemas/AccountsAnalysisRow"
            }
          },
          "turnoverByMarket": {
            "type": [
              "array",
              "null"
            ],
            "items": {
              "$ref": "#/components/schemas/AccountsAnalysisRow"
            }
          },
          "turnoverAnalysisWithheld": {
            "type": "boolean"
          },
          "priorCharges": {
            "$ref": "#/components/schemas/AccountsPriorCharges"
          },
          "operatingProfitItems": {
            "type": [
              "array",
              "null"
            ],
            "items": {
              "$ref": "#/components/schemas/AccountsAnalysisRow"
            }
          },
          "interestReceivable": {
            "type": [
              "array",
              "null"
            ],
            "items": {
              "$ref": "#/components/schemas/AccountsAnalysisRow"
            }
          },
          "interestPayable": {
            "type": [
              "array",
              "null"
            ],
            "items": {
              "$ref": "#/components/schemas/AccountsAnalysisRow"
            }
          },
          "taxCharge": {
            "type": [
              "array",
              "null"
            ],
            "items": {
              "$ref": "#/components/schemas/AccountsAnalysisRow"
            }
          },
          "stocks": {
            "type": [
              "array",
              "null"
            ],
            "items": {
              "$ref": "#/components/schemas/AccountsAnalysisRow"
            }
          },
          "fairValueInstruments": {
            "type": [
              "array",
              "null"
            ],
            "items": {
              "$ref": "#/components/schemas/AccountsAnalysisRow"
            }
          },
          "instrumentGainsAndLosses": {
            "type": [
              "array",
              "null"
            ],
            "items": {
              "$ref": "#/components/schemas/AccountsAnalysisRow"
            }
          },
          "provisions": {
            "type": [
              "array",
              "null"
            ],
            "items": {
              "$ref": "#/components/schemas/AccountsProvisionMovement"
            }
          },
          "deferredTax": {
            "type": [
              "array",
              "null"
            ],
            "items": {
              "$ref": "#/components/schemas/AccountsAnalysisRow"
            }
          }
        },
        "description": "The tables and adjustments only full FRS 102 needs."
      },
      "AccountsCharityFundRef": {
        "type": "object",
        "properties": {
          "fundClass": {
            "allOf": [
              {
                "$ref": "#/components/schemas/AccountsFundClass"
              }
            ]
          },
          "fundName": {
            "type": "string"
          }
        },
        "required": [
          "fundClass"
        ]
      },
      "AccountsCharityFundMove": {
        "type": "object",
        "properties": {
          "label": {
            "type": "string"
          },
          "account": {
            "type": "string"
          },
          "from": {
            "$ref": "#/components/schemas/AccountsCharityFundRef"
          },
          "to": {
            "$ref": "#/components/schemas/AccountsCharityFundRef"
          },
          "values": {
            "type": "array",
            "items": {
              "type": "integer"
            },
            "minItems": 2,
            "maxItems": 2,
            "description": "[this year, last year], integer pence."
          }
        },
        "description": "Moves part of an account between funds without touching the trial balance. Amounts as they sit on the line: debit positive.",
        "required": [
          "label",
          "account",
          "from",
          "to",
          "values"
        ]
      },
      "AccountsCharitySupportCost": {
        "type": "object",
        "properties": {
          "label": {
            "type": "string"
          },
          "governance": {
            "type": "boolean"
          },
          "basis": {
            "type": "string"
          },
          "values": {
            "type": "array",
            "items": {
              "type": "integer"
            },
            "minItems": 2,
            "maxItems": 2,
            "description": "[this year, last year], integer pence."
          }
        },
        "description": "SORP paras 4.62, 8.13.",
        "required": [
          "label",
          "values"
        ]
      },
      "AccountsCharityCashFlow": {
        "type": "object",
        "properties": {
          "depreciation": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "purchasesOfFixedAssets": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "proceedsOfFixedAssets": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "profitOnSaleOfFixedAssets": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "purchasesOfInvestments": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "proceedsOfInvestments": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "newBorrowing": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "borrowingRepaid": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "comparatives": {
            "type": "object",
            "additionalProperties": {
              "type": "integer"
            },
            "description": "Last year’s statement, by row key."
          }
        },
        "description": "What two balance sheets can’t say. SORP Table 11. Positive amounts, this year."
      },
      "AccountsCharityAnalyses": {
        "type": "object",
        "properties": {
          "fundMoves": {
            "type": [
              "array",
              "null"
            ],
            "items": {
              "$ref": "#/components/schemas/AccountsCharityFundMove"
            }
          },
          "supportCosts": {
            "type": [
              "array",
              "null"
            ],
            "items": {
              "$ref": "#/components/schemas/AccountsCharitySupportCost"
            }
          },
          "cashFlow": {
            "$ref": "#/components/schemas/AccountsCharityCashFlow"
          }
        }
      },
      "AccountsAnalyses": {
        "type": "object",
        "properties": {
          "fixedAssets": {
            "type": [
              "array",
              "null"
            ],
            "items": {
              "$ref": "#/components/schemas/AccountsFixedAssetClass"
            }
          },
          "debtors": {
            "type": [
              "array",
              "null"
            ],
            "items": {
              "$ref": "#/components/schemas/AccountsAnalysisRow"
            }
          },
          "creditorsWithinOneYear": {
            "type": [
              "array",
              "null"
            ],
            "items": {
              "$ref": "#/components/schemas/AccountsAnalysisRow"
            }
          },
          "creditorsAfterOneYear": {
            "type": [
              "array",
              "null"
            ],
            "items": {
              "$ref": "#/components/schemas/AccountsAnalysisRow"
            }
          },
          "amountsAfterFiveYears": {
            "type": [
              "array",
              "null"
            ],
            "items": {
              "type": "integer"
            },
            "minItems": 2,
            "maxItems": 2,
            "description": "[this year, last year], integer pence."
          },
          "securedCreditors": {
            "type": [
              "array",
              "null"
            ],
            "items": {
              "$ref": "#/components/schemas/AccountsSecuredCreditors"
            }
          },
          "full": {
            "description": "FRS102_FULL only.",
            "allOf": [
              {
                "$ref": "#/components/schemas/AccountsFullAnalyses"
              }
            ]
          },
          "charity": {
            "description": "A charity only.",
            "allOf": [
              {
                "$ref": "#/components/schemas/AccountsCharityAnalyses"
              }
            ]
          }
        },
        "description": "What supports the balance sheet lines, for FRS 102 1A notes. FRS 105 has no such notes, so they are ignored there. On a linked set with a fixed asset register, the movements come from the file."
      },
      "AccountsTbLine": {
        "type": "object",
        "properties": {
          "lineId": {
            "type": [
              "string",
              "null"
            ]
          },
          "name": {
            "type": "string"
          },
          "finalPence": {
            "type": "integer",
            "description": "This year, final. Integer pence, debit positive."
          },
          "pyPence": {
            "type": "integer",
            "description": "Last year. Integer pence, debit positive."
          },
          "fundClass": {
            "allOf": [
              {
                "$ref": "#/components/schemas/AccountsFundClass"
              }
            ]
          },
          "fundName": {
            "type": "string"
          }
        },
        "description": "One line of a version. `lineId` is its statement line.",
        "required": [
          "lineId",
          "name",
          "finalPence",
          "pyPence"
        ]
      },
      "AccountsTbVersion": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "version": {
            "type": "integer"
          },
          "source": {
            "allOf": [
              {
                "$ref": "#/components/schemas/AccountsSource"
              }
            ]
          },
          "sourceLabel": {
            "type": [
              "string",
              "null"
            ]
          },
          "createdByName": {
            "type": [
              "string",
              "null"
            ]
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "lines": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AccountsTbLine"
            }
          },
          "fixedAssetMovements": {
            "description": "The file’s fixed asset movements as read. Null for a direct version.",
            "type": [
              "array",
              "null"
            ],
            "items": {
              "$ref": "#/components/schemas/AccountsFixedAssetClass"
            }
          },
          "sourceEngagementId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          }
        },
        "description": "A trial balance as it was. Versions never change.",
        "required": [
          "id",
          "version",
          "source",
          "sourceLabel",
          "createdByName",
          "createdAt",
          "lines",
          "fixedAssetMovements",
          "sourceEngagementId"
        ]
      },
      "AccountsTbVersionSummary": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "version": {
            "type": "integer"
          },
          "source": {
            "allOf": [
              {
                "$ref": "#/components/schemas/AccountsSource"
              }
            ]
          },
          "sourceLabel": {
            "type": [
              "string",
              "null"
            ]
          },
          "createdByName": {
            "type": [
              "string",
              "null"
            ]
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "version",
          "source",
          "sourceLabel",
          "createdByName",
          "createdAt"
        ]
      },
      "AccountsProblemSeverity": {
        "type": "string",
        "enum": [
          "blocker",
          "warning"
        ],
        "description": "A blocker stops approval. A warning needs a person to look."
      },
      "AccountsNoteId": {
        "type": "string",
        "enum": [
          "reduced_disclosure",
          "judgements_estimates",
          "turnover",
          "operating_profit",
          "auditor_remuneration",
          "directors_remuneration",
          "interest_receivable",
          "interest_payable",
          "tax_on_profit",
          "intangible_assets",
          "tangible_assets",
          "fixed_asset_investments",
          "related_undertakings",
          "stocks",
          "financial_instruments",
          "deferred_tax",
          "reserves",
          "leases",
          "pensions",
          "contingencies",
          "controlling_party",
          "cash_and_net_debt",
          "general_information",
          "accounting_policies",
          "employees",
          "fixed_assets",
          "debtors",
          "creditors_within_one_year",
          "creditors_after_one_year",
          "indebtedness",
          "provisions",
          "share_capital",
          "dividends",
          "commitments",
          "off_balance_sheet",
          "exceptional_items",
          "director_advances",
          "related_parties",
          "parent_undertaking",
          "post_balance_sheet_events",
          "transition",
          "members_remuneration",
          "members_interests",
          "members_particulars",
          "capital_account",
          "charity_income",
          "charity_expenditure",
          "charity_support_costs",
          "charity_grants",
          "charity_staff",
          "charity_trustees",
          "charity_key_management",
          "charity_scrutiny_fees",
          "charity_ex_gratia",
          "charity_comparative_sofa",
          "charity_funds",
          "charity_net_assets_by_fund",
          "charity_reserves",
          "charity_other_notes",
          "partners_accounts"
        ]
      },
      "AccountsProblem": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable code."
          },
          "message": {
            "type": "string"
          },
          "severity": {
            "description": "A blocker stops approval. A warning needs a person to look.",
            "allOf": [
              {
                "$ref": "#/components/schemas/AccountsProblemSeverity"
              }
            ]
          },
          "noteId": {
            "allOf": [
              {
                "$ref": "#/components/schemas/AccountsNoteId"
              }
            ]
          }
        },
        "required": [
          "code",
          "message",
          "severity"
        ]
      },
      "AccountsSize": {
        "type": "object",
        "properties": {
          "size": {
            "allOf": [
              {
                "$ref": "#/components/schemas/AccountsCompanySize"
              }
            ]
          },
          "needsLastYear": {
            "type": "boolean",
            "description": "It turns on how the company qualified last year, and nobody has said."
          },
          "excluded": {
            "type": "boolean",
            "description": "CA 2006 ss384, 467 take it out, whatever the figures say."
          },
          "reasons": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "source": {
            "type": "string",
            "description": "Which law’s limits were used."
          }
        },
        "description": "Full FRS 102: how the company qualifies (CA 2006 ss382, 465, 466, 467), and why.",
        "required": [
          "size",
          "needsLastYear",
          "excluded",
          "reasons",
          "source"
        ]
      },
      "AccountsCharityScrutiny": {
        "type": "string",
        "enum": [
          "none",
          "examination",
          "qualified_examination",
          "audit"
        ]
      },
      "AccountsCharityFiling": {
        "type": "object",
        "properties": {
          "jurisdiction": {
            "allOf": [
              {
                "$ref": "#/components/schemas/AccountsCharityJurisdiction"
              }
            ]
          },
          "regulator": {
            "type": "string"
          },
          "due": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "what": {
            "type": "string"
          },
          "source": {
            "type": "string"
          }
        },
        "description": "What goes to a regulator and when. Tolvi doesn’t send it.",
        "required": [
          "jurisdiction",
          "regulator",
          "due",
          "what",
          "source"
        ]
      },
      "AccountsCharityQuestionForce": {
        "type": "string",
        "enum": [
          "must",
          "should",
          "may"
        ]
      },
      "AccountsCharityQuestion": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "group": {
            "type": "string"
          },
          "ask": {
            "type": "string"
          },
          "reference": {
            "type": "string"
          },
          "force": {
            "allOf": [
              {
                "$ref": "#/components/schemas/AccountsCharityQuestionForce"
              }
            ]
          },
          "orNone": {
            "type": "boolean",
            "description": "“None” is a fair answer."
          }
        },
        "description": "One question for the trustees’ annual report. `must` unanswered is a blocker, `should` a warning.",
        "required": [
          "id",
          "group",
          "ask",
          "reference",
          "force",
          "orNone"
        ]
      },
      "AccountsCharityReporting": {
        "type": "object",
        "properties": {
          "jurisdiction": {
            "allOf": [
              {
                "$ref": "#/components/schemas/AccountsCharityJurisdiction"
              }
            ]
          },
          "tier": {
            "type": [
              "number",
              "null"
            ],
            "description": "SORP para 35. Null on receipts and payments."
          },
          "grossIncomePence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "grossAssetsPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "scrutiny": {
            "allOf": [
              {
                "$ref": "#/components/schemas/AccountsCharityScrutiny"
              }
            ]
          },
          "scrutinyLabel": {
            "type": "string"
          },
          "scrutinyBasis": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "mayUseReceiptsAndPayments": {
            "type": "boolean"
          },
          "mustUseAccruals": {
            "type": "boolean"
          },
          "companySmall": {
            "type": [
              "boolean",
              "null"
            ],
            "description": "A charitable company only, on this year’s figures."
          },
          "cashFlowRequired": {
            "type": "boolean"
          },
          "sorp2026Applies": {
            "type": "boolean"
          },
          "filing": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AccountsCharityFiling"
            }
          },
          "noRegulatorFiling": {
            "type": "string"
          },
          "questions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AccountsCharityQuestion"
            }
          }
        },
        "description": "What this charity must do this year, from its figures and the dated law. Nothing goes to a regulator from Tolvi.",
        "required": [
          "jurisdiction",
          "tier",
          "grossIncomePence",
          "grossAssetsPence",
          "scrutiny",
          "scrutinyLabel",
          "scrutinyBasis",
          "mayUseReceiptsAndPayments",
          "mustUseAccruals",
          "companySmall",
          "cashFlowRequired",
          "sorp2026Applies",
          "filing",
          "noRegulatorFiling",
          "questions"
        ]
      },
      "AccountsVariant": {
        "type": "string",
        "enum": [
          "full",
          "filleted"
        ],
        "description": "`full` is for members. `filleted` is the copy prepared for Companies House: no profit and loss account and no directors’ report."
      },
      "AccountsPeriod": {
        "type": "object",
        "properties": {
          "start": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "end": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "priorStart": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "priorEnd": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          }
        },
        "required": [
          "start",
          "end"
        ]
      },
      "AccountsSectionKind": {
        "type": "string",
        "enum": [
          "front_matter",
          "revision_statement",
          "company_information",
          "strategic_report",
          "directors_report",
          "auditors_report",
          "accountants_report",
          "trustees_report",
          "examiners_report",
          "table_statement",
          "profit_and_loss",
          "comprehensive_income",
          "balance_sheet",
          "changes_in_equity",
          "cash_flow",
          "notes"
        ]
      },
      "AccountsInformationEntry": {
        "type": "object",
        "properties": {
          "label": {
            "type": "string"
          },
          "value": {
            "type": "string"
          }
        },
        "required": [
          "label",
          "value"
        ]
      },
      "AccountsStrategicConcept": {
        "type": "string",
        "enum": [
          "fair_review",
          "principal_risks",
          "kpis",
          "non_financial",
          "section_172",
          "sustainability"
        ]
      },
      "AccountsStrategicParagraph": {
        "type": "object",
        "properties": {
          "heading": {
            "type": "string"
          },
          "text": {
            "type": "string"
          },
          "concept": {
            "allOf": [
              {
                "$ref": "#/components/schemas/AccountsStrategicConcept"
              }
            ]
          }
        },
        "required": [
          "heading",
          "text",
          "concept"
        ]
      },
      "AccountsTrusteesReportGroup": {
        "type": "object",
        "properties": {
          "heading": {
            "type": "string"
          },
          "paragraphs": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        },
        "required": [
          "heading",
          "paragraphs"
        ]
      },
      "AccountsTableUnit": {
        "type": "string",
        "enum": [
          "pence",
          "count"
        ]
      },
      "AccountsColumn": {
        "type": "object",
        "properties": {
          "label": {
            "type": "string"
          }
        },
        "required": [
          "label"
        ]
      },
      "AccountsRowKind": {
        "type": "string",
        "enum": [
          "line",
          "sub",
          "total",
          "heading"
        ]
      },
      "AccountsTableRow": {
        "type": "object",
        "properties": {
          "label": {
            "type": "string"
          },
          "values": {
            "type": "array",
            "items": {
              "type": [
                "integer",
                "null"
              ]
            },
            "description": "One cell per column. Whole pounds in pence for `unit: pence`, plain numbers for `count`. Null is blank."
          },
          "kind": {
            "allOf": [
              {
                "$ref": "#/components/schemas/AccountsRowKind"
              }
            ]
          }
        },
        "required": [
          "label",
          "values"
        ]
      },
      "AccountsTable": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "unit": {
            "allOf": [
              {
                "$ref": "#/components/schemas/AccountsTableUnit"
              }
            ]
          },
          "columns": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AccountsColumn"
            }
          },
          "rows": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AccountsTableRow"
            }
          }
        },
        "required": [
          "id",
          "unit",
          "columns",
          "rows"
        ]
      },
      "AccountsSignature": {
        "type": "object",
        "properties": {
          "name": {
            "type": [
              "string",
              "null"
            ]
          },
          "capacity": {
            "type": "string"
          },
          "date": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31",
            "description": "Blank until a person records the approval."
          }
        },
        "required": [
          "name",
          "capacity",
          "date"
        ]
      },
      "AccountsStatementLine": {
        "type": "object",
        "properties": {
          "label": {
            "type": "string"
          },
          "values": {
            "type": "array",
            "items": {
              "type": [
                "integer",
                "null"
              ]
            },
            "description": "[this year, last year]: whole pounds, in pence. Null is blank. Signed: income, assets and equity positive; costs and liabilities negative."
          },
          "kind": {
            "allOf": [
              {
                "$ref": "#/components/schemas/AccountsRowKind"
              }
            ]
          },
          "indent": {
            "type": "boolean"
          },
          "note": {
            "type": "integer",
            "description": "The number of the note that supports this line."
          }
        },
        "required": [
          "label",
          "values",
          "kind"
        ]
      },
      "AccountsStatutoryStatement": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "text": {
            "type": "string"
          },
          "reference": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "text",
          "reference"
        ]
      },
      "AccountsNote": {
        "type": "object",
        "properties": {
          "id": {
            "allOf": [
              {
                "$ref": "#/components/schemas/AccountsNoteId"
              }
            ]
          },
          "number": {
            "type": "integer",
            "description": "1-based, in order of appearance."
          },
          "title": {
            "type": "string"
          },
          "paragraphs": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "tables": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AccountsTable"
            }
          },
          "overridden": {
            "type": "boolean",
            "description": "Edited wording replaced the default."
          },
          "references": {
            "description": "Authority for the note.",
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        },
        "required": [
          "id",
          "number",
          "title",
          "paragraphs",
          "tables",
          "overridden",
          "references"
        ]
      },
      "AccountsSection": {
        "type": "object",
        "properties": {
          "kind": {
            "allOf": [
              {
                "$ref": "#/components/schemas/AccountsSectionKind"
              }
            ]
          },
          "title": {
            "type": "string"
          },
          "companyName": {
            "type": "string",
            "description": "front_matter."
          },
          "registeredNumber": {
            "type": "string",
            "description": "front_matter."
          },
          "subtitle": {
            "type": "string",
            "description": "front_matter."
          },
          "contents": {
            "description": "front_matter: the titles of the sections that follow.",
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "entries": {
            "description": "company_information.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AccountsInformationEntry"
            }
          },
          "paragraphs": {
            "description": "directors_report, revision_statement and auditors_report.",
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "strategicParagraphs": {
            "description": "strategic_report: a person’s words, under headings.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AccountsStrategicParagraph"
            }
          },
          "opinion": {
            "description": "auditors_report.",
            "oneOf": [
              {
                "$ref": "#/components/schemas/AccountsAuditOpinion"
              },
              {
                "type": "null"
              }
            ]
          },
          "auditorName": {
            "type": [
              "string",
              "null"
            ],
            "description": "auditors_report."
          },
          "seniorStatutoryAuditor": {
            "type": [
              "string",
              "null"
            ],
            "description": "auditors_report."
          },
          "reportDate": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31",
            "description": "auditors_report."
          },
          "address": {
            "type": [
              "string",
              "null"
            ],
            "description": "auditors_report and accountants_report."
          },
          "firmName": {
            "type": [
              "string",
              "null"
            ],
            "description": "accountants_report."
          },
          "groups": {
            "description": "trustees_report: a person’s answers, under the SORP’s headings.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AccountsTrusteesReportGroup"
            }
          },
          "declarations": {
            "description": "trustees_report: fixed company law statements.",
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "examinerName": {
            "type": [
              "string",
              "null"
            ],
            "description": "examiners_report."
          },
          "qualification": {
            "type": [
              "string",
              "null"
            ],
            "description": "examiners_report."
          },
          "qualifyingBasis": {
            "type": [
              "string",
              "null"
            ],
            "description": "examiners_report."
          },
          "tables": {
            "description": "changes_in_equity: one table a year, a column for each component. table_statement: the SoFA, a receipts and payments account or a statement of assets and liabilities, a column for each class of fund.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AccountsTable"
            }
          },
          "keys": {
            "description": "cash_flow: a stable key for each row.",
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "originalApprovedOn": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31",
            "description": "revision_statement."
          },
          "revisionApprovedOn": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31",
            "description": "revision_statement: null until recorded."
          },
          "references": {
            "description": "revision_statement: the authority for it.",
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "smallCompaniesStatement": {
            "type": "string",
            "description": "directors_report: the s419(2) statement."
          },
          "signature": {
            "description": "directors_report and balance_sheet.",
            "allOf": [
              {
                "$ref": "#/components/schemas/AccountsSignature"
              }
            ]
          },
          "columns": {
            "description": "profit_and_loss, comprehensive_income, balance_sheet and cash_flow.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AccountsColumn"
            }
          },
          "rows": {
            "description": "profit_and_loss, comprehensive_income, balance_sheet and cash_flow.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AccountsStatementLine"
            }
          },
          "statements": {
            "description": "balance_sheet: directly above the signature, in this order.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AccountsStatutoryStatement"
            }
          },
          "roundingNote": {
            "type": "string",
            "description": "balance_sheet."
          },
          "atFootOfBalanceSheet": {
            "type": "boolean",
            "description": "notes: FRS 105 para 6.2, the notes sit at the foot of the balance sheet."
          },
          "notes": {
            "description": "notes.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AccountsNote"
            }
          }
        },
        "description": "One section, ready to render. `kind` says which of the other fields it has.",
        "required": [
          "kind",
          "title"
        ]
      },
      "AccountsDocument": {
        "type": "object",
        "properties": {
          "entity": {
            "description": "Left out: a company.",
            "allOf": [
              {
                "$ref": "#/components/schemas/AccountsEntity"
              }
            ]
          },
          "framework": {
            "allOf": [
              {
                "$ref": "#/components/schemas/AccountsFramework"
              }
            ]
          },
          "variant": {
            "description": "`full` is for members. `filleted` is the copy prepared for Companies House: no profit and loss account and no directors’ report.",
            "allOf": [
              {
                "$ref": "#/components/schemas/AccountsVariant"
              }
            ]
          },
          "period": {
            "$ref": "#/components/schemas/AccountsPeriod"
          },
          "sections": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AccountsSection"
            }
          }
        },
        "description": "The accounts, ordered and ready to render.",
        "required": [
          "framework",
          "variant",
          "period",
          "sections"
        ]
      },
      "AccountsDocuments": {
        "type": "object",
        "properties": {
          "full": {
            "$ref": "#/components/schemas/AccountsDocument"
          },
          "filleted": {
            "$ref": "#/components/schemas/AccountsDocument"
          }
        },
        "description": "Both variants, or the one asked for."
      },
      "ApproverRole": {
        "type": "string",
        "enum": [
          "partner",
          "manager"
        ],
        "description": "Who may approve in this firm: partners only, or managers and partners."
      },
      "AccountsReviewPointStatus": {
        "type": "string",
        "enum": [
          "open",
          "cleared"
        ]
      },
      "AccountsReviewPoint": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "area": {
            "type": [
              "string",
              "null"
            ]
          },
          "text": {
            "type": "string"
          },
          "status": {
            "allOf": [
              {
                "$ref": "#/components/schemas/AccountsReviewPointStatus"
              }
            ]
          },
          "raisedByName": {
            "type": [
              "string",
              "null"
            ]
          },
          "clearedByName": {
            "type": [
              "string",
              "null"
            ]
          },
          "clearedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "area",
          "text",
          "status",
          "raisedByName",
          "clearedByName",
          "clearedAt",
          "createdAt"
        ]
      },
      "AccountsIxbrlProblemSeverity": {
        "type": "string",
        "enum": [
          "blocker",
          "warning"
        ]
      },
      "AccountsIxbrlProblem": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string"
          },
          "severity": {
            "allOf": [
              {
                "$ref": "#/components/schemas/AccountsIxbrlProblemSeverity"
              }
            ]
          },
          "message": {
            "type": "string"
          }
        },
        "required": [
          "code",
          "severity",
          "message"
        ]
      },
      "AccountsIxbrlVersion": {
        "type": "object",
        "properties": {
          "readyToFile": {
            "type": "boolean",
            "description": "Whether anything Tolvi can check stops this file being filed. It doesn’t mean Companies House or HMRC would accept it."
          },
          "problems": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AccountsIxbrlProblem"
            }
          }
        },
        "required": [
          "readyToFile",
          "problems"
        ]
      },
      "AccountsIxbrlSummary": {
        "type": "object",
        "properties": {
          "full": {
            "$ref": "#/components/schemas/AccountsIxbrlVersion"
          },
          "filleted": {
            "$ref": "#/components/schemas/AccountsIxbrlVersion"
          }
        },
        "description": "What stops each tagged file being filed. Download it from `GET /accounts/{id}/ixbrl`.",
        "required": [
          "full",
          "filleted"
        ]
      },
      "ChSubmissionMode": {
        "type": "string",
        "enum": [
          "test",
          "live"
        ]
      },
      "ChSubmissionStatus": {
        "type": "string",
        "enum": [
          "pending",
          "received",
          "parked",
          "accepted",
          "rejected",
          "unknown"
        ]
      },
      "ChSubmission": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "variant": {
            "allOf": [
              {
                "$ref": "#/components/schemas/AccountsVariant"
              }
            ]
          },
          "mode": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ChSubmissionMode"
              }
            ]
          },
          "status": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ChSubmissionStatus"
              }
            ]
          },
          "statusText": {
            "type": "string",
            "description": "In plain words, for the screen."
          },
          "submissionNumber": {
            "type": "string",
            "description": "Quote this to Companies House."
          },
          "reasons": {
            "description": "Why it was refused, in plain words.",
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "examinerComment": {
            "type": [
              "string",
              "null"
            ]
          },
          "receivedAt": {
            "type": [
              "string",
              "null"
            ],
            "description": "The gateway’s timestamp, when it gave one."
          },
          "submittedByName": {
            "type": [
              "string",
              "null"
            ]
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "description": "One attempt to deliver these accounts to Companies House.",
        "required": [
          "id",
          "variant",
          "mode",
          "status",
          "statusText",
          "submissionNumber",
          "reasons",
          "examinerComment",
          "receivedAt",
          "submittedByName",
          "createdAt"
        ]
      },
      "ChFilingState": {
        "type": "object",
        "properties": {
          "filingEnabled": {
            "type": "boolean"
          },
          "cannotFileReason": {
            "type": [
              "string",
              "null"
            ],
            "description": "Why filing can’t be started now, in plain words. Null when it can."
          },
          "submissions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ChSubmission"
            }
          }
        },
        "description": "Delivering these accounts to Companies House. Switched off until Companies House’s test service has been passed.",
        "required": [
          "filingEnabled",
          "cannotFileReason",
          "submissions"
        ]
      },
      "AccountsRevisionFacts": {
        "type": "object",
        "properties": {
          "originalApprovedOn": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31",
            "description": "The date the board approved the accounts these replace."
          },
          "nonCompliance": {
            "type": "string",
            "description": "The respects in which the original accounts did not comply with the Companies Act 2006."
          },
          "consequentialAmendments": {
            "type": [
              "string",
              "null"
            ],
            "description": "Significant amendments made as a consequence. Null is none."
          }
        },
        "description": "What SI 2008/373 reg 4(2)(a) needs stated in revised accounts.",
        "required": [
          "originalApprovedOn"
        ]
      },
      "AccountsSet": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "clientId": {
            "type": "string",
            "format": "uuid"
          },
          "clientName": {
            "type": "string"
          },
          "dueDate": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31",
            "description": "When they’re due at Companies House (CA 2006 s442, for an LLP as applied by SI 2008/1911). Non-statutory accounts have no such date: this is the self assessment date they work towards."
          },
          "periodStart": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "periodEnd": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "framework": {
            "allOf": [
              {
                "$ref": "#/components/schemas/AccountsFramework"
              }
            ]
          },
          "entity": {
            "allOf": [
              {
                "$ref": "#/components/schemas/AccountsEntity"
              }
            ]
          },
          "source": {
            "allOf": [
              {
                "$ref": "#/components/schemas/AccountsSource"
              }
            ]
          },
          "status": {
            "allOf": [
              {
                "$ref": "#/components/schemas/AccountsStatus"
              }
            ]
          },
          "approvedOn": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          },
          "revisionNumber": {
            "type": "integer",
            "description": "0 for the original accounts, 1 for the first revision."
          },
          "supersededBySetId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid",
            "description": "Set once approved revised accounts have replaced these."
          },
          "nextStep": {
            "type": [
              "string",
              "null"
            ],
            "description": "In the list: the first thing stopping approval. Null when nothing is. A linked file isn’t read for the list, so open the set to see whether it has changed."
          },
          "blockingProblems": {
            "type": "integer",
            "description": "In the list: how many problems stop approval."
          },
          "corporationTaxReturnIds": {
            "description": "Company Tax Returns these accounts go with. Ids only.",
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "recordFacts": {
            "description": "What the client’s record says now, to compare with what these accounts state.",
            "allOf": [
              {
                "$ref": "#/components/schemas/CompanyFacts"
              }
            ]
          },
          "priorStart": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31"
          },
          "priorEnd": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31"
          },
          "engagementId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "sourceChanged": {
            "type": "boolean",
            "description": "The Working Papers file’s figures differ from this set’s. Always false for a direct set."
          },
          "sourceState": {
            "$ref": "#/components/schemas/AccountsSourceState"
          },
          "company": {
            "$ref": "#/components/schemas/AccountsCompany"
          },
          "inputs": {
            "$ref": "#/components/schemas/AccountsInputs"
          },
          "analyses": {
            "$ref": "#/components/schemas/AccountsAnalyses"
          },
          "noteOverrides": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            },
            "description": "Replacement wording by note id; paragraphs separated by a blank line. Tables always come from the figures."
          },
          "currentVersion": {
            "description": "Null until a trial balance is entered or a file is linked.",
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/AccountsTbVersion"
              }
            ]
          },
          "versions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AccountsTbVersionSummary"
            }
          },
          "figuresHash": {
            "type": "string",
            "description": "Fingerprint of everything on the accounts. Any change moves it. Send it back to approve."
          },
          "signatoryName": {
            "type": [
              "string",
              "null"
            ]
          },
          "approvedByName": {
            "type": [
              "string",
              "null"
            ]
          },
          "approvedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "rolledFromSetId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "problems": {
            "description": "Everything that stops the accounts being finished.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AccountsProblem"
            }
          },
          "size": {
            "description": "FRS102_FULL only.",
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/AccountsSize"
              }
            ]
          },
          "charity": {
            "description": "A charity only.",
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/AccountsCharityReporting"
              }
            ]
          },
          "canApprove": {
            "type": "boolean"
          },
          "cannotApproveReason": {
            "type": [
              "string",
              "null"
            ]
          },
          "documents": {
            "$ref": "#/components/schemas/AccountsDocuments"
          },
          "approverRole": {
            "description": "Who may approve in this firm: partners only, or managers and partners.",
            "allOf": [
              {
                "$ref": "#/components/schemas/ApproverRole"
              }
            ]
          },
          "reviewPoints": {
            "description": "Open points stop the approval.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AccountsReviewPoint"
            }
          },
          "reviewerNames": {
            "description": "Who sending for review goes to, by name: the client’s partner, or every partner where the record names none, and its manager.",
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "ixbrl": {
            "$ref": "#/components/schemas/AccountsIxbrlSummary"
          },
          "companiesHouse": {
            "$ref": "#/components/schemas/ChFilingState"
          },
          "revisionOfSetId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid",
            "description": "The approved set these revised accounts replace."
          },
          "revision": {
            "description": "Revised accounts only.",
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/AccountsRevisionFacts"
              }
            ]
          },
          "revisedBySetId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid",
            "description": "Revised accounts started from this set, approved or not."
          },
          "revisionDeliverBy": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31",
            "description": "Approved revised accounts: 28 days from the date of revision (SI 2008/373 regs 12, 14)."
          }
        },
        "description": "A company’s accounts for one period end. Draft until people record the directors’ approval.",
        "required": [
          "id",
          "clientId",
          "clientName",
          "periodStart",
          "periodEnd",
          "framework",
          "entity",
          "source",
          "status",
          "approvedOn",
          "updatedAt",
          "corporationTaxReturnIds",
          "priorStart",
          "priorEnd",
          "engagementId",
          "sourceChanged",
          "sourceState",
          "company",
          "inputs",
          "analyses",
          "noteOverrides",
          "currentVersion",
          "versions",
          "figuresHash",
          "signatoryName",
          "approvedByName",
          "approvedAt",
          "rolledFromSetId",
          "problems",
          "size",
          "charity",
          "canApprove",
          "cannotApproveReason",
          "documents",
          "approverRole",
          "reviewPoints",
          "reviewerNames",
          "ixbrl",
          "companiesHouse",
          "revisionOfSetId",
          "revision",
          "revisedBySetId",
          "revisionDeliverBy"
        ]
      },
      "AccountsStatement": {
        "type": "string",
        "enum": [
          "balance_sheet",
          "equity",
          "profit_and_loss"
        ]
      },
      "AccountsNormalBalance": {
        "type": "string",
        "enum": [
          "debit",
          "credit"
        ],
        "description": "The side a balance usually sits on."
      },
      "AccountsStatementLineOption": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "label": {
            "type": "string"
          },
          "statement": {
            "allOf": [
              {
                "$ref": "#/components/schemas/AccountsStatement"
              }
            ]
          },
          "normalBalance": {
            "description": "The side a balance usually sits on.",
            "allOf": [
              {
                "$ref": "#/components/schemas/AccountsNormalBalance"
              }
            ]
          },
          "notUnderFrs105": {
            "type": "boolean",
            "description": "Not allowed under FRS 105 para 24.7."
          },
          "format": {
            "description": "Full FRS 102: the profit and loss format this line belongs to.",
            "allOf": [
              {
                "$ref": "#/components/schemas/AccountsPlFormat"
              }
            ]
          },
          "oci": {
            "type": "boolean",
            "description": "Full FRS 102: other comprehensive income."
          }
        },
        "required": [
          "id",
          "label",
          "statement",
          "normalBalance"
        ]
      },
      "AccountsStatementLines": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AccountsStatementLineOption"
            }
          }
        },
        "required": [
          "items"
        ]
      },
      "AccountsRevisionInput": {
        "type": "object",
        "properties": {
          "nonCompliance": {
            "type": "string",
            "maxLength": 4000,
            "description": "The respects in which the original accounts did not comply with the Companies Act 2006."
          },
          "consequentialAmendments": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 4000,
            "description": "Significant amendments made as a consequence. Null is none."
          }
        }
      },
      "UpdateAccountsSetRequest": {
        "type": "object",
        "properties": {
          "framework": {
            "allOf": [
              {
                "$ref": "#/components/schemas/AccountsFramework"
              }
            ]
          },
          "company": {
            "$ref": "#/components/schemas/AccountsCompany"
          },
          "inputs": {
            "$ref": "#/components/schemas/AccountsInputs"
          },
          "analyses": {
            "$ref": "#/components/schemas/AccountsAnalyses"
          },
          "noteOverrides": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            },
            "description": "Replacement wording by note id; paragraphs separated by a blank line. Tables always come from the figures."
          },
          "expectedFiguresHash": {
            "type": "string",
            "description": "The `figuresHash` you were looking at. 409 if the set has changed since."
          },
          "revision": {
            "description": "Revised accounts only.",
            "allOf": [
              {
                "$ref": "#/components/schemas/AccountsRevisionInput"
              }
            ]
          }
        },
        "description": "Each part given replaces that part whole, so a fact can be taken back to not answered by leaving it out. Any real change to an approved set returns it to draft and loses the approval."
      },
      "TbImportFormat": {
        "type": "string",
        "enum": [
          "csv",
          "sheet",
          "json"
        ]
      },
      "TbSheet": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "maxLength": 100,
            "description": "Worksheet name, used as the source label when there is no file name."
          },
          "firstRow": {
            "type": "integer",
            "minimum": 1,
            "description": "Spreadsheet row number of rows[0], for messages. Default 1."
          },
          "rows": {
            "type": "array",
            "maxItems": 20000,
            "items": {
              "type": "array",
              "maxItems": 50,
              "items": {
                "oneOf": [
                  {
                    "type": "string",
                    "maxLength": 500
                  },
                  {
                    "type": "number"
                  },
                  {
                    "type": "boolean"
                  },
                  {
                    "type": "null"
                  }
                ]
              }
            },
            "description": "The worksheet’s cells, row by row."
          }
        },
        "description": "One worksheet read from a workbook (.xlsx/.xls) by the caller, e.g. SheetJS `sheet_to_json(ws, { header: 1, raw: true })`. Dates as YYYY-MM-DD strings.",
        "required": [
          "rows"
        ]
      },
      "TbColumns": {
        "type": "object",
        "properties": {
          "headerRow": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 1,
            "maximum": 1000000
          },
          "code": {
            "type": "integer",
            "minimum": 0,
            "maximum": 49
          },
          "name": {
            "type": "integer",
            "minimum": 0,
            "maximum": 49
          },
          "type": {
            "type": "integer",
            "minimum": 0,
            "maximum": 49,
            "description": "Account type (asset, liability…), when the file has one."
          },
          "debit": {
            "type": "integer",
            "minimum": 0,
            "maximum": 49
          },
          "credit": {
            "type": "integer",
            "minimum": 0,
            "maximum": 49
          },
          "balance": {
            "type": "integer",
            "minimum": 0,
            "maximum": 49
          },
          "pyDebit": {
            "type": "integer",
            "minimum": 0,
            "maximum": 49
          },
          "pyCredit": {
            "type": "integer",
            "minimum": 0,
            "maximum": 49
          },
          "pyBalance": {
            "type": "integer",
            "minimum": 0,
            "maximum": 49
          }
        },
        "description": "Which row holds the column headings and which column holds each part of the trial balance. Columns are numbered from 0; headerRow is the 1-based line (CSV) or row (worksheet) number, null when there is no header row. This year needs Debit and Credit, or one signed Balance column (debit positive); the prior year is optional and read the same way.",
        "required": [
          "headerRow"
        ]
      },
      "AccountsTbPreviewRequest": {
        "type": "object",
        "properties": {
          "format": {
            "allOf": [
              {
                "$ref": "#/components/schemas/TbImportFormat"
              }
            ]
          },
          "content": {
            "type": "string",
            "maxLength": 2000000
          },
          "sheet": {
            "$ref": "#/components/schemas/TbSheet"
          },
          "asAt": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "sourceLabel": {
            "type": "string"
          },
          "columns": {
            "description": "Read these columns instead of detecting them.",
            "allOf": [
              {
                "$ref": "#/components/schemas/TbColumns"
              }
            ]
          }
        },
        "description": "A spreadsheet or CSV to read. Nothing is stored.",
        "required": [
          "format"
        ]
      },
      "AccountsTbPreviewLine": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "thisYearPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "lastYearPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "statementLine": {
            "type": [
              "string",
              "null"
            ],
            "description": "The statement line Tolvi suggests, from the client’s and the firm’s mappings. Null when nothing fits: a person chooses."
          }
        },
        "required": [
          "code",
          "name",
          "thisYearPence",
          "lastYearPence",
          "statementLine"
        ]
      },
      "TbWarning": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string"
          },
          "message": {
            "type": "string"
          }
        },
        "required": [
          "code",
          "message"
        ]
      },
      "AccountsTbPreview": {
        "type": "object",
        "properties": {
          "lines": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AccountsTbPreviewLine"
            }
          },
          "warnings": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TbWarning"
            }
          },
          "problems": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AccountsProblem"
            }
          },
          "layout": {
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/TbColumns"
              }
            ]
          }
        },
        "description": "What a file holds. Nothing is stored: choose the statement lines, then post the new version.",
        "required": [
          "lines",
          "warnings",
          "problems",
          "layout"
        ]
      },
      "AccountsTbLineInput": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string"
          },
          "statementLine": {
            "type": "string",
            "description": "A statement line id from `GET /accounts/statement-lines`."
          },
          "thisYearPence": {
            "type": "integer",
            "description": "Integer pence. Debit positive, credit negative."
          },
          "lastYearPence": {
            "type": "integer",
            "description": "Integer pence. Debit positive, credit negative."
          },
          "fundClass": {
            "description": "Charities only (SORP module 2). Left out: the general fund.",
            "allOf": [
              {
                "$ref": "#/components/schemas/AccountsFundClass"
              }
            ]
          },
          "fundName": {
            "type": "string",
            "description": "The individual fund within its class."
          }
        },
        "required": [
          "name",
          "statementLine",
          "thisYearPence"
        ]
      },
      "AccountsTbNewVersionRequest": {
        "type": "object",
        "properties": {
          "lines": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AccountsTbLineInput"
            }
          },
          "sourceLabel": {
            "type": "string"
          }
        },
        "required": [
          "lines"
        ]
      },
      "LinkAccountsSetRequest": {
        "type": "object",
        "properties": {
          "engagementId": {
            "type": "string",
            "format": "uuid",
            "description": "A Working Papers engagement of the same client, with the same year end."
          }
        },
        "required": [
          "engagementId"
        ]
      },
      "RollForwardAccountsSetRequest": {
        "type": "object",
        "properties": {
          "periodEnd": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31",
            "description": "Left out: twelve months on."
          }
        }
      },
      "SendAccountsForReviewRequest": {
        "type": "object",
        "properties": {
          "note": {
            "type": "string"
          }
        }
      },
      "ApproveAccountsSetRequest": {
        "type": "object",
        "properties": {
          "figuresHash": {
            "type": "string",
            "description": "The `figuresHash` you reviewed."
          },
          "approvedOn": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31",
            "description": "The date the board approved the accounts."
          },
          "signatoryName": {
            "type": "string",
            "description": "The director signing the balance sheet."
          }
        },
        "required": [
          "figuresHash",
          "approvedOn",
          "signatoryName"
        ]
      },
      "ReopenAccountsSetRequest": {
        "type": "object",
        "properties": {
          "note": {
            "type": "string"
          }
        }
      },
      "ReviseAccountsSetRequest": {
        "type": "object",
        "properties": {
          "nonCompliance": {
            "type": "string",
            "maxLength": 4000,
            "description": "The respects in which the original accounts did not comply with the Companies Act 2006."
          },
          "consequentialAmendments": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 4000,
            "description": "Significant amendments made as a consequence. Null is none."
          }
        }
      },
      "RaiseAccountsReviewPointRequest": {
        "type": "object",
        "properties": {
          "text": {
            "type": "string",
            "minLength": 1,
            "maxLength": 2000
          },
          "area": {
            "type": "string",
            "maxLength": 200,
            "description": "Which part of the accounts it’s about."
          }
        },
        "required": [
          "text"
        ]
      },
      "DraftAccountsNoteRequest": {
        "type": "object",
        "properties": {
          "noteId": {
            "allOf": [
              {
                "$ref": "#/components/schemas/AccountsNoteId"
              }
            ]
          },
          "instructions": {
            "type": "string"
          },
          "estimateOnly": {
            "type": "boolean",
            "description": "Only say what it would cost."
          }
        },
        "required": [
          "noteId"
        ]
      },
      "AccountsNoteDraft": {
        "type": "object",
        "properties": {
          "noteId": {
            "allOf": [
              {
                "$ref": "#/components/schemas/AccountsNoteId"
              }
            ]
          },
          "wording": {
            "type": [
              "string",
              "null"
            ],
            "description": "Null with `estimateOnly`."
          },
          "assumptions": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "warnings": {
            "description": "Things to fix before accepting it, such as an amount of money in the wording.",
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "tokens": {
            "type": "integer"
          },
          "affordable": {
            "type": "boolean",
            "description": "False when the estimate is more than the balance or the person’s limit allows."
          },
          "reason": {
            "type": [
              "string",
              "null"
            ]
          },
          "model": {
            "type": [
              "string",
              "null"
            ]
          },
          "promptVersion": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "description": "Wording for a person to check. Nothing is stored or applied: to accept it, save it through `noteOverrides`.",
        "required": [
          "noteId",
          "wording",
          "assumptions",
          "warnings",
          "tokens",
          "affordable",
          "reason",
          "model",
          "promptVersion"
        ]
      },
      "SubmitAccountsToCompaniesHouseRequest": {
        "type": "object",
        "properties": {
          "figuresHash": {
            "type": "string",
            "description": "The `figuresHash` you reviewed."
          },
          "variant": {
            "allOf": [
              {
                "$ref": "#/components/schemas/AccountsVariant"
              }
            ]
          },
          "presenterAccountId": {
            "type": "string",
            "format": "uuid"
          },
          "companyAuthenticationCode": {
            "type": "string",
            "minLength": 6,
            "maxLength": 8,
            "description": "The company’s authentication code. Used for this message only and not stored."
          }
        },
        "required": [
          "figuresHash",
          "variant",
          "presenterAccountId",
          "companyAuthenticationCode"
        ]
      },
      "ChCredentialStatus": {
        "type": "string",
        "enum": [
          "not_saved",
          "saved",
          "needs_update"
        ]
      },
      "ChPresenter": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "credentialStatus": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ChCredentialStatus"
              }
            ]
          },
          "presenterHint": {
            "type": [
              "string",
              "null"
            ]
          },
          "lastUsedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "name",
          "credentialStatus",
          "presenterHint",
          "lastUsedAt"
        ]
      },
      "ChPresenterList": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ChPresenter"
            }
          },
          "canStoreCredentials": {
            "type": "boolean",
            "description": "Whether presenter details can be stored on this Tolvi."
          }
        },
        "required": [
          "items",
          "canStoreCredentials"
        ]
      },
      "CreateChPresenterRequest": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 80,
            "example": "Leeds office"
          }
        },
        "required": [
          "name"
        ]
      },
      "SaveChCredentialsRequest": {
        "type": "object",
        "properties": {
          "presenterId": {
            "type": "string",
            "minLength": 1,
            "maxLength": 100
          },
          "authenticationCode": {
            "type": "string",
            "minLength": 1,
            "maxLength": 200
          }
        },
        "required": [
          "presenterId",
          "authenticationCode"
        ]
      },
      "CtReturnStatus": {
        "type": "string",
        "enum": [
          "draft",
          "in_review",
          "approved",
          "filing",
          "filed"
        ]
      },
      "CtSource": {
        "type": "string",
        "enum": [
          "typed",
          "working_papers",
          "accounts"
        ]
      },
      "CtSubmissionStatus": {
        "type": "string",
        "enum": [
          "pending",
          "acknowledged",
          "accepted",
          "rejected",
          "unknown"
        ],
        "description": "How the latest attempt to send this return ended. Null if it has never been sent."
      },
      "CtReturnType": {
        "type": "string",
        "enum": [
          "new",
          "amended"
        ],
        "description": "What goes in the XML’s `ReturnType`."
      },
      "CtReturnRow": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "clientId": {
            "type": "string",
            "format": "uuid"
          },
          "clientName": {
            "type": "string"
          },
          "groupId": {
            "type": "string",
            "format": "uuid",
            "description": "Shared by the returns of one period of account."
          },
          "periodOfAccountStart": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "periodOfAccountEnd": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "periodStart": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "periodEnd": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "periodIndex": {
            "type": "integer",
            "description": "This return’s place among the accounting periods, from 0."
          },
          "periodCount": {
            "type": "integer"
          },
          "status": {
            "allOf": [
              {
                "$ref": "#/components/schemas/CtReturnStatus"
              }
            ]
          },
          "source": {
            "allOf": [
              {
                "$ref": "#/components/schemas/CtSource"
              }
            ]
          },
          "dueDate": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31",
            "description": "When the return is due (FA 1998 Sch 18 para 14)."
          },
          "openReviewPoints": {
            "type": "integer"
          },
          "taxDue": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Tax still to pay on this return, in integer pence, negative when overpaid. Null until it has figures the tax engine can work out."
          },
          "clientConfirmationCurrent": {
            "type": "boolean",
            "description": "The client confirmed these figures, not earlier ones."
          },
          "lastSubmissionStatus": {
            "description": "How the latest attempt to send this return ended. Null if it has never been sent.",
            "oneOf": [
              {
                "$ref": "#/components/schemas/CtSubmissionStatus"
              },
              {
                "type": "null"
              }
            ]
          },
          "filingEnabled": {
            "type": "boolean",
            "description": "Whether filing is switched on: off until HMRC’s test service passes."
          },
          "returnType": {
            "description": "What goes in the XML’s `ReturnType`.",
            "allOf": [
              {
                "$ref": "#/components/schemas/CtReturnType"
              }
            ]
          },
          "amendsReturnId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid",
            "description": "The return this amends. That one stays unchanged."
          },
          "amendmentNumber": {
            "type": "integer",
            "description": "1 for the first amendment. Nil on a new return."
          },
          "filedElsewhereOn": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31",
            "description": "A person recorded it as filed outside Tolvi on this day."
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "clientId",
          "clientName",
          "groupId",
          "periodOfAccountStart",
          "periodOfAccountEnd",
          "periodStart",
          "periodEnd",
          "periodIndex",
          "periodCount",
          "status",
          "source",
          "dueDate",
          "openReviewPoints",
          "taxDue",
          "clientConfirmationCurrent",
          "lastSubmissionStatus",
          "filingEnabled",
          "returnType",
          "amendsReturnId",
          "amendmentNumber",
          "filedElsewhereOn",
          "updatedAt"
        ]
      },
      "CtReturnList": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CtReturnRow"
            }
          }
        },
        "required": [
          "items"
        ]
      },
      "CreateCtReturnRequest": {
        "type": "object",
        "properties": {
          "clientId": {
            "type": "string",
            "format": "uuid"
          },
          "periodStart": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31",
            "description": "Start of the period of account. Accounting periods starting before 1 April 2023 are refused."
          },
          "periodEnd": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31",
            "description": "End of the period of account, at most 18 months on."
          }
        },
        "description": "A period of account over 12 months makes one return for each accounting period.",
        "required": [
          "clientId",
          "periodStart",
          "periodEnd"
        ]
      },
      "CtProblemSeverity": {
        "type": "string",
        "enum": [
          "block",
          "warn"
        ],
        "description": "block: stops filing, not approving or downloading. warn: a person should look."
      },
      "CtProblemArea": {
        "type": "string",
        "enum": [
          "ct600",
          "computation",
          "accounts",
          "source",
          "xml"
        ]
      },
      "CtProblem": {
        "type": "object",
        "properties": {
          "severity": {
            "description": "block: stops filing, not approving or downloading. warn: a person should look.",
            "allOf": [
              {
                "$ref": "#/components/schemas/CtProblemSeverity"
              }
            ]
          },
          "code": {
            "type": "string"
          },
          "box": {
            "type": "string"
          },
          "area": {
            "allOf": [
              {
                "$ref": "#/components/schemas/CtProblemArea"
              }
            ]
          },
          "message": {
            "type": "string"
          }
        },
        "required": [
          "severity",
          "code",
          "area",
          "message"
        ]
      },
      "CtSourceState": {
        "type": "object",
        "properties": {
          "source": {
            "allOf": [
              {
                "$ref": "#/components/schemas/CtSource"
              }
            ]
          },
          "engagementId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "accountsSetId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "sourceChanged": {
            "type": "boolean",
            "description": "A linked source differs from what this return holds. The figures here haven’t moved: refresh to bring the change in."
          },
          "sourceApproved": {
            "type": [
              "boolean",
              "null"
            ],
            "description": "Whether the linked file or set is approved. Null with nothing linked."
          },
          "message": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "source",
          "engagementId",
          "accountsSetId",
          "sourceChanged",
          "sourceApproved",
          "message"
        ]
      },
      "CtInputVersion": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "version": {
            "type": "integer"
          },
          "source": {
            "allOf": [
              {
                "$ref": "#/components/schemas/CtSource"
              }
            ]
          },
          "fingerprint": {
            "type": "string"
          },
          "sourceLabel": {
            "type": [
              "string",
              "null"
            ]
          },
          "createdByName": {
            "type": [
              "string",
              "null"
            ]
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "version",
          "source",
          "fingerprint",
          "sourceLabel",
          "createdByName",
          "createdAt"
        ]
      },
      "CtRelatedReturn": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "periodStart": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "periodEnd": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "status": {
            "allOf": [
              {
                "$ref": "#/components/schemas/CtReturnStatus"
              }
            ]
          }
        },
        "required": [
          "id",
          "periodStart",
          "periodEnd",
          "status"
        ]
      },
      "CtFilingMode": {
        "type": "string",
        "enum": [
          "test",
          "test_in_live",
          "live"
        ]
      },
      "CtAmendmentHistoryItem": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "amendmentNumber": {
            "type": "integer"
          },
          "status": {
            "allOf": [
              {
                "$ref": "#/components/schemas/CtReturnStatus"
              }
            ]
          },
          "filedElsewhereOn": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "amendmentNumber",
          "status",
          "filedElsewhereOn",
          "updatedAt"
        ]
      },
      "CtReviewPointStatus": {
        "type": "string",
        "enum": [
          "open",
          "cleared"
        ]
      },
      "CtReviewPoint": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "box": {
            "type": [
              "string",
              "null"
            ]
          },
          "text": {
            "type": "string"
          },
          "status": {
            "allOf": [
              {
                "$ref": "#/components/schemas/CtReviewPointStatus"
              }
            ]
          },
          "raisedByName": {
            "type": [
              "string",
              "null"
            ]
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "box",
          "text",
          "status",
          "raisedByName",
          "createdAt"
        ]
      },
      "CtEvent": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "kind": {
            "type": "string"
          },
          "actorName": {
            "type": [
              "string",
              "null"
            ]
          },
          "note": {
            "type": [
              "string",
              "null"
            ]
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "kind",
          "actorName",
          "note",
          "createdAt"
        ]
      },
      "CtSubmission": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "mode": {
            "allOf": [
              {
                "$ref": "#/components/schemas/CtFilingMode"
              }
            ]
          },
          "status": {
            "allOf": [
              {
                "$ref": "#/components/schemas/CtSubmissionStatus"
              }
            ]
          },
          "correlationId": {
            "type": [
              "string",
              "null"
            ]
          },
          "irmark": {
            "type": "string"
          },
          "errors": {
            "description": "HMRC’s errors: { number, text, location, meaning }. `meaning` says it in plain words.",
            "type": [
              "array",
              "null"
            ],
            "items": {
              "type": "object"
            }
          },
          "message": {
            "type": [
              "string",
              "null"
            ],
            "description": "What happened, in plain words."
          },
          "receiptAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "submittedByName": {
            "type": [
              "string",
              "null"
            ]
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "mode",
          "status",
          "correlationId",
          "irmark",
          "errors",
          "message",
          "receiptAt",
          "submittedByName",
          "createdAt"
        ]
      },
      "CtReturn": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "clientId": {
            "type": "string",
            "format": "uuid"
          },
          "clientName": {
            "type": "string"
          },
          "groupId": {
            "type": "string",
            "format": "uuid",
            "description": "Shared by the returns of one period of account."
          },
          "periodOfAccountStart": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "periodOfAccountEnd": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "periodStart": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "periodEnd": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "periodIndex": {
            "type": "integer",
            "description": "This return’s place among the accounting periods, from 0."
          },
          "periodCount": {
            "type": "integer"
          },
          "status": {
            "allOf": [
              {
                "$ref": "#/components/schemas/CtReturnStatus"
              }
            ]
          },
          "source": {
            "allOf": [
              {
                "$ref": "#/components/schemas/CtSource"
              }
            ]
          },
          "dueDate": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31",
            "description": "When the return is due (FA 1998 Sch 18 para 14)."
          },
          "openReviewPoints": {
            "type": "integer"
          },
          "taxDue": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Tax still to pay on this return, in integer pence, negative when overpaid. Null until it has figures the tax engine can work out."
          },
          "clientConfirmationCurrent": {
            "type": "boolean",
            "description": "The client confirmed these figures, not earlier ones."
          },
          "lastSubmissionStatus": {
            "description": "How the latest attempt to send this return ended. Null if it has never been sent.",
            "oneOf": [
              {
                "$ref": "#/components/schemas/CtSubmissionStatus"
              },
              {
                "type": "null"
              }
            ]
          },
          "filingEnabled": {
            "type": "boolean",
            "description": "Whether filing is switched on: off until HMRC’s test service passes."
          },
          "returnType": {
            "description": "What goes in the XML’s `ReturnType`.",
            "allOf": [
              {
                "$ref": "#/components/schemas/CtReturnType"
              }
            ]
          },
          "amendsReturnId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid",
            "description": "The return this amends. That one stays unchanged."
          },
          "amendmentNumber": {
            "type": "integer",
            "description": "1 for the first amendment. Nil on a new return."
          },
          "filedElsewhereOn": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31",
            "description": "A person recorded it as filed outside Tolvi on this day."
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          },
          "recordFacts": {
            "description": "What the client’s record says now, to compare with what the return states.",
            "allOf": [
              {
                "$ref": "#/components/schemas/CompanyFacts"
              }
            ]
          },
          "boxes": {
            "type": [
              "object",
              "null"
            ],
            "additionalProperties": true,
            "description": "{ boxes, financialYears, loans }: CT600 and CT600A boxes by number. Money is integer pence, whole pounds where the form says so. Bank details are masked. Null without figures."
          },
          "problems": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CtProblem"
            }
          },
          "computation": {
            "type": [
              "object",
              "null"
            ],
            "additionalProperties": true,
            "description": "The engine’s computation for this accounting period, with the period of account’s adjustments. Null without figures."
          },
          "input": {
            "type": [
              "object",
              "null"
            ],
            "additionalProperties": true,
            "description": "The engine input now held, in integer pence."
          },
          "facts": {
            "type": "object",
            "additionalProperties": true,
            "description": "What a person has answered."
          },
          "masks": {
            "type": "object",
            "additionalProperties": true,
            "description": "Masked bank details."
          },
          "sourceState": {
            "$ref": "#/components/schemas/CtSourceState"
          },
          "sourceChanged": {
            "type": "boolean"
          },
          "versions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CtInputVersion"
            }
          },
          "relatedReturns": {
            "description": "The other returns of a long period of account.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CtRelatedReturn"
            }
          },
          "returnHash": {
            "type": "string",
            "description": "Send this back when approving: it fingerprints the return."
          },
          "utr": {
            "type": [
              "string",
              "null"
            ]
          },
          "registrationNumber": {
            "type": [
              "string",
              "null"
            ]
          },
          "approvedByName": {
            "type": [
              "string",
              "null"
            ]
          },
          "approvedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "clientConfirmedOn": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31"
          },
          "approverRole": {
            "description": "Who may approve in this firm: partners only, or managers and partners.",
            "allOf": [
              {
                "$ref": "#/components/schemas/ApproverRole"
              }
            ]
          },
          "reviewerNames": {
            "description": "Who sending for review goes to, by name: the client’s partner, or every partner where the record names none, and its manager.",
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "canApprove": {
            "type": "boolean"
          },
          "cannotApproveReason": {
            "type": [
              "string",
              "null"
            ]
          },
          "canFile": {
            "type": "boolean",
            "description": "No blocker stands in the way of filing this return, whether or not filing is switched on."
          },
          "canSubmit": {
            "type": "boolean"
          },
          "cannotSubmitReason": {
            "type": [
              "string",
              "null"
            ]
          },
          "filingMode": {
            "allOf": [
              {
                "$ref": "#/components/schemas/CtFilingMode"
              }
            ]
          },
          "declaration": {
            "type": "object",
            "additionalProperties": true,
            "description": "{ version, text }: the declaration to accept before filing."
          },
          "rolledFromReturnId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "canAmend": {
            "type": "boolean"
          },
          "cannotAmendReason": {
            "type": [
              "string",
              "null"
            ]
          },
          "lastAmendmentDay": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31",
            "description": "The last day this return can be amended: 12 months after its filing date (FA 1998 Sch 18 para 15(4))."
          },
          "amendedByReturnId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid",
            "description": "The amendment of this return, once started."
          },
          "amendmentHistory": {
            "description": "Every version of this return, oldest first. Each keeps its own review and approval.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CtAmendmentHistoryItem"
            }
          },
          "reviewPoints": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CtReviewPoint"
            }
          },
          "events": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CtEvent"
            }
          },
          "submissions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CtSubmission"
            }
          }
        },
        "description": "A Company Tax Return for one accounting period, with its boxes, computation and what stands in the way of filing.",
        "required": [
          "id",
          "clientId",
          "clientName",
          "groupId",
          "periodOfAccountStart",
          "periodOfAccountEnd",
          "periodStart",
          "periodEnd",
          "periodIndex",
          "periodCount",
          "status",
          "source",
          "dueDate",
          "openReviewPoints",
          "taxDue",
          "clientConfirmationCurrent",
          "lastSubmissionStatus",
          "filingEnabled",
          "returnType",
          "amendsReturnId",
          "amendmentNumber",
          "filedElsewhereOn",
          "updatedAt",
          "boxes",
          "problems",
          "computation",
          "input",
          "facts",
          "masks",
          "sourceState",
          "sourceChanged",
          "versions",
          "relatedReturns",
          "returnHash",
          "utr",
          "registrationNumber",
          "approvedByName",
          "approvedAt",
          "clientConfirmedOn",
          "approverRole",
          "reviewerNames",
          "canApprove",
          "cannotApproveReason",
          "canFile",
          "canSubmit",
          "cannotSubmitReason",
          "filingMode",
          "declaration",
          "rolledFromReturnId",
          "canAmend",
          "cannotAmendReason",
          "lastAmendmentDay",
          "amendedByReturnId",
          "amendmentHistory",
          "reviewPoints",
          "events",
          "submissions"
        ]
      },
      "UpdateCtReturnRequest": {
        "type": "object",
        "properties": {
          "input": {
            "type": "object",
            "additionalProperties": true,
            "description": "Parts of the tax engine’s input to change, in integer pence. Applies to every return of the period of account. `researchAndDevelopment: null` removes a claim. Figures that come from a linked source can’t be changed here."
          },
          "facts": {
            "type": "object",
            "additionalProperties": true,
            "description": "Answers: declarationName, declarationStatus, exports, repaymentClaim, provisionalFigures, rnd (companySize, notificationSubmitted, additionalInformationSubmitted, payeReferences, connectedPayeReferences), amendment (accountsAlreadySubmitted, computationsAlreadySubmitted), outOfScope and so on."
          },
          "bank": {
            "type": [
              "object",
              "null"
            ],
            "additionalProperties": true,
            "description": "Bank details for a repayment, or null to remove them. Encrypted, and only ever shown masked."
          },
          "note": {
            "type": "string"
          }
        }
      },
      "CtGroupNotice": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "kind": {
            "type": "string",
            "enum": [
              "current",
              "carried_forward"
            ]
          },
          "surrenderingClientId": {
            "type": "string",
            "format": "uuid"
          },
          "surrenderingName": {
            "type": "string"
          },
          "surrenderingUtr": {
            "type": [
              "string",
              "null"
            ]
          },
          "claimantClientId": {
            "type": "string",
            "format": "uuid"
          },
          "claimantName": {
            "type": "string"
          },
          "claimantUtr": {
            "type": [
              "string",
              "null"
            ]
          },
          "surrenderPeriodStart": {
            "type": "string",
            "format": "date"
          },
          "surrenderPeriodEnd": {
            "type": "string",
            "format": "date"
          },
          "amountPence": {
            "type": "number"
          },
          "givenOn": {
            "type": "string",
            "format": "date"
          },
          "status": {
            "type": "string",
            "enum": [
              "given",
              "withdrawn"
            ]
          },
          "gaps": {
            "description": "What the notice lacks under FA 1998 Sch 18 para 71(1). A notice with gaps is ineffective.",
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        },
        "required": [
          "id",
          "kind",
          "surrenderingClientId",
          "surrenderingName",
          "surrenderingUtr",
          "claimantClientId",
          "claimantName",
          "claimantUtr",
          "surrenderPeriodStart",
          "surrenderPeriodEnd",
          "amountPence",
          "givenOn",
          "status",
          "gaps"
        ]
      },
      "CtGroupCompanySuggestion": {
        "type": "object",
        "properties": {
          "clientId": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "utr": {
            "type": [
              "string",
              "null"
            ]
          },
          "why": {
            "type": "string",
            "description": "How the client record connects the two. A pointer only."
          },
          "looksLike75Percent": {
            "type": "boolean",
            "description": "The links would meet 75% ownership if they’re complete. Never decides the group test."
          }
        },
        "required": [
          "clientId",
          "name",
          "utr",
          "why",
          "looksLike75Percent"
        ]
      },
      "CtGroupReliefState": {
        "type": "object",
        "properties": {
          "notices": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CtGroupNotice"
            }
          },
          "relatedCompanies": {
            "description": "Companies the client record connects with this one. Suggestions: nothing is applied.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CtGroupCompanySuggestion"
            }
          },
          "associatedCompaniesSuggested": {
            "type": "number",
            "description": "A count from the links for boxes 326 to 328, for a person to accept or ignore. Never applied by itself."
          },
          "associatedCompaniesNote": {
            "type": "string"
          }
        },
        "required": [
          "notices",
          "relatedCompanies",
          "associatedCompaniesSuggested",
          "associatedCompaniesNote"
        ]
      },
      "CreateCtGroupNoticeRequest": {
        "type": "object",
        "properties": {
          "kind": {
            "type": "string",
            "enum": [
              "current",
              "carried_forward"
            ]
          },
          "thisCompanyIs": {
            "type": "string",
            "enum": [
              "surrendering",
              "claimant"
            ],
            "description": "Which side this return’s company is on."
          },
          "otherClientId": {
            "type": "string",
            "format": "uuid",
            "description": "The other company: a client of this firm."
          },
          "surrenderPeriod": {
            "type": "object",
            "properties": {
              "start": {
                "type": "string",
                "format": "date"
              },
              "end": {
                "type": "string",
                "format": "date"
              }
            },
            "required": [
              "start",
              "end"
            ],
            "description": "The surrendering company’s accounting period."
          },
          "amountPence": {
            "type": "number",
            "description": "Whole pounds, in pence."
          },
          "givenOn": {
            "type": "string",
            "format": "date",
            "description": "When notice was given to HMRC (FA 1998 Sch 18 para 70(3))."
          }
        },
        "description": "A notice of consent to surrender group relief, given to HMRC.",
        "required": [
          "kind",
          "thisCompanyIs",
          "otherClientId",
          "amountPence",
          "givenOn"
        ]
      },
      "CtLinkSource": {
        "type": "string",
        "enum": [
          "typed",
          "working_papers",
          "accounts",
          "accounts_file"
        ],
        "description": "working_papers: a snapshot of the file’s tax computation. accounts: profit and turnover from an approved Accounts set, and its accounts. accounts_file: only the accounts that go with the return. typed: keep the figures and stop following a source."
      },
      "LinkCtSourceRequest": {
        "type": "object",
        "properties": {
          "source": {
            "description": "working_papers: a snapshot of the file’s tax computation. accounts: profit and turnover from an approved Accounts set, and its accounts. accounts_file: only the accounts that go with the return. typed: keep the figures and stop following a source.",
            "allOf": [
              {
                "$ref": "#/components/schemas/CtLinkSource"
              }
            ]
          },
          "engagementId": {
            "type": "string",
            "format": "uuid"
          },
          "accountsSetId": {
            "type": "string",
            "format": "uuid"
          }
        },
        "required": [
          "source"
        ]
      },
      "RollForwardCtReturnRequest": {
        "type": "object",
        "properties": {
          "periodEnd": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31",
            "description": "End of the next period of account. Defaults to 12 months on."
          }
        }
      },
      "CtNoteRequest": {
        "type": "object",
        "properties": {
          "note": {
            "type": "string",
            "maxLength": 2000
          }
        }
      },
      "RaiseCtReviewPointRequest": {
        "type": "object",
        "properties": {
          "text": {
            "type": "string",
            "minLength": 1,
            "maxLength": 4000
          },
          "box": {
            "type": "string",
            "description": "The CT600 box it’s about."
          }
        },
        "required": [
          "text"
        ]
      },
      "ApproveCtReturnRequest": {
        "type": "object",
        "properties": {
          "returnHash": {
            "type": "string",
            "description": "The `returnHash` you reviewed."
          },
          "note": {
            "type": "string"
          }
        },
        "required": [
          "returnHash"
        ]
      },
      "RecordCtFiledElsewhereRequest": {
        "type": "object",
        "properties": {
          "filedOn": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31",
            "description": "The day it went to HMRC by other means. This is a record a person makes, not HMRC’s word."
          },
          "note": {
            "type": "string",
            "maxLength": 2000
          }
        },
        "required": [
          "filedOn"
        ]
      },
      "RecordCtClientConfirmationRequest": {
        "type": "object",
        "properties": {
          "confirmedOn": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "note": {
            "type": "string"
          },
          "returnHash": {
            "type": "string",
            "description": "The `returnHash` of the copy the client confirmed."
          }
        },
        "required": [
          "confirmedOn",
          "returnHash"
        ]
      },
      "SubmitCtReturnRequest": {
        "type": "object",
        "properties": {
          "returnHash": {
            "type": "string"
          },
          "agentAccountId": {
            "type": "string",
            "format": "uuid"
          },
          "declaration": {
            "type": "object",
            "additionalProperties": true,
            "description": "{ accepted: true, version }: the declaration on the CT600."
          }
        },
        "required": [
          "returnHash",
          "agentAccountId",
          "declaration"
        ]
      },
      "CtCredentialStatus": {
        "type": "string",
        "enum": [
          "not_saved",
          "saved",
          "needs_update"
        ]
      },
      "CtAgentAccount": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "credentialStatus": {
            "allOf": [
              {
                "$ref": "#/components/schemas/CtCredentialStatus"
              }
            ]
          },
          "userIdHint": {
            "type": [
              "string",
              "null"
            ]
          },
          "lastUsedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "name",
          "credentialStatus",
          "userIdHint",
          "lastUsedAt"
        ]
      },
      "CtAgentAccountList": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CtAgentAccount"
            }
          },
          "canStoreCredentials": {
            "type": "boolean",
            "description": "Whether sign-ins can be stored on this Tolvi."
          }
        },
        "required": [
          "items",
          "canStoreCredentials"
        ]
      },
      "CreateCtAgentAccountRequest": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 80,
            "example": "Leeds office"
          }
        },
        "required": [
          "name"
        ]
      },
      "SaveCtCredentialsRequest": {
        "type": "object",
        "properties": {
          "userId": {
            "type": "string",
            "minLength": 1,
            "maxLength": 100
          },
          "password": {
            "type": "string",
            "minLength": 1,
            "maxLength": 200
          }
        },
        "required": [
          "userId",
          "password"
        ]
      },
      "SaReturnType": {
        "type": "string",
        "enum": [
          "sa100",
          "sa800",
          "sa900"
        ]
      },
      "SaReturnStatus": {
        "type": "string",
        "enum": [
          "draft",
          "in_review",
          "approved",
          "filing",
          "filed"
        ]
      },
      "SaReturnRow": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "clientId": {
            "type": "string",
            "format": "uuid"
          },
          "clientName": {
            "type": "string"
          },
          "taxYearEnd": {
            "type": "integer"
          },
          "returnType": {
            "allOf": [
              {
                "$ref": "#/components/schemas/SaReturnType"
              }
            ]
          },
          "taxYear": {
            "type": "string",
            "example": "2025/26"
          },
          "status": {
            "allOf": [
              {
                "$ref": "#/components/schemas/SaReturnStatus"
              }
            ]
          },
          "dueDate": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "daysLeft": {
            "type": "integer",
            "description": "Days to the online deadline; negative when overdue."
          },
          "openReviewPoints": {
            "type": "integer",
            "description": "Open review points."
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "clientId",
          "clientName",
          "taxYearEnd",
          "returnType",
          "taxYear",
          "status",
          "dueDate",
          "daysLeft",
          "openReviewPoints",
          "updatedAt"
        ]
      },
      "SaReturnList": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SaReturnRow"
            }
          },
          "taxYearEnds": {
            "description": "Tax years Tolvi can prepare, by the year they end.",
            "type": "array",
            "items": {
              "type": "integer"
            }
          }
        },
        "required": [
          "items",
          "taxYearEnds"
        ]
      },
      "CreateSaReturnRequest": {
        "type": "object",
        "properties": {
          "clientId": {
            "type": "string",
            "format": "uuid"
          },
          "taxYearEnd": {
            "type": "integer",
            "description": "The year the tax year ends: 2026 is 2025/26. Tolvi can prepare 2025/26 onwards.",
            "example": 2026
          },
          "returnType": {
            "description": "SA100 unless said otherwise. An SA800 needs a partnership or LLP client.",
            "allOf": [
              {
                "$ref": "#/components/schemas/SaReturnType"
              }
            ]
          }
        },
        "required": [
          "clientId",
          "taxYearEnd"
        ]
      },
      "SaPriorYearFigures": {
        "type": "object",
        "properties": {
          "taxYearEnd": {
            "type": "integer"
          },
          "figures": {
            "type": "object",
            "additionalProperties": {
              "type": "integer"
            },
            "description": "Pence, by field."
          }
        },
        "description": "Last year’s figures, brought in for comparison. On no return and in no calculation.",
        "required": [
          "taxYearEnd",
          "figures"
        ]
      },
      "SaReturnPartner": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "description": "As on the partnership statement."
          },
          "utr": {
            "type": "string",
            "description": "Ten digits."
          },
          "shareBps": {
            "type": "integer",
            "description": "Profit share in basis points. Across the partners they add up to 10000."
          },
          "clientId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid",
            "description": "Their own client record at this firm: their SA100 is offered their SA104 as a suggestion."
          },
          "dateAppointed": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31"
          },
          "dateCeased": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31"
          }
        },
        "required": [
          "name",
          "utr",
          "shareBps"
        ]
      },
      "SaPrepMode": {
        "type": "string",
        "enum": [
          "simple_step",
          "ai",
          "full"
        ],
        "description": "How it’s being prepared, once someone has chosen."
      },
      "SaProblem": {
        "type": "object",
        "properties": {
          "page": {
            "type": "string",
            "example": "SA102"
          },
          "box": {
            "type": "string",
            "example": "EMP4"
          },
          "message": {
            "type": "string"
          }
        },
        "required": [
          "page",
          "box",
          "message"
        ]
      },
      "SaFilingMode": {
        "type": "string",
        "enum": [
          "test",
          "test_in_live",
          "live"
        ]
      },
      "SaReviewPointStatus": {
        "type": "string",
        "enum": [
          "open",
          "cleared"
        ]
      },
      "SaReviewPoint": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "boxKey": {
            "type": [
              "string",
              "null"
            ]
          },
          "text": {
            "type": "string"
          },
          "status": {
            "allOf": [
              {
                "$ref": "#/components/schemas/SaReviewPointStatus"
              }
            ]
          },
          "raisedByName": {
            "type": [
              "string",
              "null"
            ]
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "boxKey",
          "text",
          "status",
          "raisedByName",
          "createdAt"
        ]
      },
      "SaEvent": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "kind": {
            "type": "string"
          },
          "actorName": {
            "type": [
              "string",
              "null"
            ]
          },
          "note": {
            "type": [
              "string",
              "null"
            ]
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "kind",
          "actorName",
          "note",
          "createdAt"
        ]
      },
      "SaSubmissionMode": {
        "type": "string",
        "enum": [
          "test",
          "test_in_live",
          "live"
        ],
        "description": "test and test_in_live never reach a taxpayer’s record."
      },
      "SaSubmissionStatus": {
        "type": "string",
        "enum": [
          "pending",
          "acknowledged",
          "accepted",
          "rejected",
          "unknown"
        ]
      },
      "SaSubmission": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "mode": {
            "description": "test and test_in_live never reach a taxpayer’s record.",
            "allOf": [
              {
                "$ref": "#/components/schemas/SaSubmissionMode"
              }
            ]
          },
          "status": {
            "allOf": [
              {
                "$ref": "#/components/schemas/SaSubmissionStatus"
              }
            ]
          },
          "correlationId": {
            "type": [
              "string",
              "null"
            ]
          },
          "irmark": {
            "type": "string"
          },
          "errors": {
            "description": "HMRC’s errors: { number, text, location }.",
            "type": [
              "array",
              "null"
            ],
            "items": {
              "type": "object"
            }
          },
          "message": {
            "type": [
              "string",
              "null"
            ],
            "description": "What this means, in plain words."
          },
          "receiptAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "submittedByName": {
            "type": [
              "string",
              "null"
            ]
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "mode",
          "status",
          "correlationId",
          "irmark",
          "errors",
          "message",
          "receiptAt",
          "submittedByName",
          "createdAt"
        ]
      },
      "SaReturn": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "clientId": {
            "type": "string",
            "format": "uuid"
          },
          "clientName": {
            "type": "string"
          },
          "taxYearEnd": {
            "type": "integer"
          },
          "returnType": {
            "allOf": [
              {
                "$ref": "#/components/schemas/SaReturnType"
              }
            ]
          },
          "taxYear": {
            "type": "string",
            "example": "2025/26"
          },
          "status": {
            "allOf": [
              {
                "$ref": "#/components/schemas/SaReturnStatus"
              }
            ]
          },
          "dueDate": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "daysLeft": {
            "type": "integer",
            "description": "Days to the online deadline; negative when overdue."
          },
          "openReviewPoints": {
            "type": "integer",
            "description": "Open review points."
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          },
          "importedLastYear": {
            "description": "Last year’s figures brought in from other software, if any. For comparison: on no return and in no calculation.",
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/SaPriorYearFigures"
              }
            ]
          },
          "partners": {
            "description": "SA800 only: who shares the statement.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SaReturnPartner"
            }
          },
          "trustKind": {
            "type": [
              "string",
              "null"
            ],
            "description": "SA900 only: what the return says it is, in words."
          },
          "pages": {
            "type": "object",
            "additionalProperties": true,
            "description": "Box values by page: { sa100: { INC1: 12000 }, sa102: [{ EMP1: 4000000 }] }. Money is integer pence. Sensitive boxes aren’t here."
          },
          "sources": {
            "type": "object",
            "additionalProperties": true,
            "description": "Where figures came from, keyed sa102.0.EMP1. For AI Mode: { source: \"ai\", evidence: [{ kind, label, quote, value, documentId, documentPage }], reviewedAt }."
          },
          "masks": {
            "type": "object",
            "additionalProperties": true,
            "description": "Masked National Insurance number, date of birth and bank details."
          },
          "otherPayments": {
            "type": "object",
            "additionalProperties": true,
            "description": "{ paymentsOnAccountMade, otherPaymentsMade } in pence."
          },
          "prepMode": {
            "description": "How it’s being prepared, once someone has chosen.",
            "oneOf": [
              {
                "$ref": "#/components/schemas/SaPrepMode"
              },
              {
                "type": "null"
              }
            ]
          },
          "aiFiguresToConfirm": {
            "type": "integer",
            "description": "Figures AI filled that a person hasn’t checked. It can’t go for review until this is nil."
          },
          "calculation": {
            "type": "object",
            "additionalProperties": true,
            "description": "{ c, cal, sa302, unsupported, filable }: HMRC’s calculation for the pages Tolvi covers."
          },
          "problems": {
            "description": "What HMRC’s rules would refuse.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SaProblem"
            }
          },
          "returnHash": {
            "type": "string",
            "description": "Send this back when approving: it fingerprints the figures."
          },
          "utr": {
            "type": [
              "string",
              "null"
            ]
          },
          "approvedByName": {
            "type": [
              "string",
              "null"
            ]
          },
          "approvedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "clientApprovedOn": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31"
          },
          "clientApprovalCurrent": {
            "type": "boolean",
            "description": "The client approved these figures, not earlier ones."
          },
          "approverRole": {
            "description": "Who may approve in this firm: partners only, or managers and partners.",
            "allOf": [
              {
                "$ref": "#/components/schemas/ApproverRole"
              }
            ]
          },
          "canApprove": {
            "type": "boolean"
          },
          "cannotApproveReason": {
            "type": [
              "string",
              "null"
            ]
          },
          "canSubmit": {
            "type": "boolean"
          },
          "cannotSubmitReason": {
            "type": [
              "string",
              "null"
            ]
          },
          "filingEnabled": {
            "type": "boolean",
            "description": "Whether filing is switched on: off until HMRC has approved Tolvi."
          },
          "filingMode": {
            "allOf": [
              {
                "$ref": "#/components/schemas/SaFilingMode"
              }
            ]
          },
          "declaration": {
            "type": "object",
            "additionalProperties": true,
            "description": "{ version, text }: the declaration to accept before filing."
          },
          "reviewPoints": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SaReviewPoint"
            }
          },
          "events": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SaEvent"
            }
          },
          "submissions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SaSubmission"
            }
          }
        },
        "description": "A client’s SA100 for one tax year, with the calculation and what stands in the way of filing.",
        "required": [
          "id",
          "clientId",
          "clientName",
          "taxYearEnd",
          "returnType",
          "taxYear",
          "status",
          "dueDate",
          "daysLeft",
          "openReviewPoints",
          "updatedAt",
          "importedLastYear",
          "partners",
          "trustKind",
          "pages",
          "sources",
          "masks",
          "otherPayments",
          "prepMode",
          "aiFiguresToConfirm",
          "calculation",
          "problems",
          "returnHash",
          "utr",
          "approvedByName",
          "approvedAt",
          "clientApprovedOn",
          "clientApprovalCurrent",
          "approverRole",
          "canApprove",
          "cannotApproveReason",
          "canSubmit",
          "cannotSubmitReason",
          "filingEnabled",
          "filingMode",
          "declaration",
          "reviewPoints",
          "events",
          "submissions"
        ]
      },
      "SaQuestionKind": {
        "type": "string",
        "enum": [
          "yesno",
          "count"
        ]
      },
      "SaQuestion": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "text": {
            "type": "string"
          },
          "help": {
            "type": "string"
          },
          "kind": {
            "allOf": [
              {
                "$ref": "#/components/schemas/SaQuestionKind"
              }
            ]
          },
          "section": {
            "type": "string",
            "description": "The SA100 section a yes opens."
          },
          "outOfScope": {
            "type": "object",
            "additionalProperties": true,
            "description": "{ form, title }: a page Tolvi can’t prepare yet, if the answer is yes."
          }
        },
        "required": [
          "id",
          "text",
          "kind"
        ]
      },
      "SaPlanStep": {
        "type": "object",
        "properties": {
          "key": {
            "type": "string",
            "example": "sa102.0"
          },
          "title": {
            "type": "string"
          },
          "page": {
            "type": "string",
            "example": "sa102"
          },
          "instance": {
            "type": [
              "integer",
              "null"
            ]
          },
          "boxes": {
            "description": "The boxes on this step. Null means every box on the page.",
            "type": [
              "array",
              "null"
            ],
            "items": {
              "type": "string"
            }
          }
        },
        "required": [
          "key",
          "title",
          "page",
          "instance",
          "boxes"
        ]
      },
      "SaPlan": {
        "type": "object",
        "properties": {
          "questionnaireVersion": {
            "type": "string"
          },
          "questions": {
            "description": "The questions that apply, given the answers.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SaQuestion"
            }
          },
          "answers": {
            "type": "object",
            "additionalProperties": true,
            "description": "Answers so far."
          },
          "unanswered": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "complete": {
            "type": "boolean"
          },
          "pagesNeeded": {
            "type": "object",
            "additionalProperties": true,
            "description": "{ sa102: 2, sa103s: 0, ... }."
          },
          "outOfScope": {
            "description": "{ form, title }: pages the answers call for that can’t be filed from Tolvi.",
            "type": "array",
            "items": {
              "type": "object"
            }
          },
          "steps": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SaPlanStep"
            }
          },
          "extraPages": {
            "description": "{ page, instance }: pages with figures the answers no longer call for. A person decides.",
            "type": "array",
            "items": {
              "type": "object"
            }
          },
          "prepMode": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/SaPrepMode"
              },
              {
                "type": "null"
              }
            ]
          },
          "suggested": {
            "type": "object",
            "additionalProperties": true,
            "description": "{ questionId: { value, why } }: answers Tolvi can suggest from last year, the client’s record and what HMRC holds. None counts until a person accepts it."
          }
        },
        "description": "Which pages and steps a return needs, from the answers so far. Nothing counts as a no until it’s answered.",
        "required": [
          "questionnaireVersion",
          "questions",
          "answers",
          "unanswered",
          "complete",
          "pagesNeeded",
          "outOfScope",
          "steps",
          "extraPages",
          "prepMode"
        ]
      },
      "SaveSaAnswersRequest": {
        "type": "object",
        "properties": {
          "answers": {
            "type": "object",
            "additionalProperties": true,
            "description": "{ questionId: true, otherId: 2 }."
          },
          "prepMode": {
            "allOf": [
              {
                "$ref": "#/components/schemas/SaPrepMode"
              }
            ]
          }
        },
        "description": "Answers merge over what’s there. Pages are added to match, and empty pages no longer needed are removed. Pages with figures are never removed.",
        "required": [
          "answers"
        ]
      },
      "UpdateSaReturnRequest": {
        "type": "object",
        "properties": {
          "changes": {
            "description": "{ page, instance?, box, value, source? }. Box is HMRC’s mnemonic, such as INC1; money is integer pence; null clears.",
            "type": "array",
            "items": {
              "type": "object"
            }
          },
          "addPages": {
            "description": "Pages to add: sa101, sa102, sa102m, sa103f, sa103s, sa103l, sa104f, sa104s, sa105, sa106, sa107, sa108, sa109.",
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "removePages": {
            "description": "{ page, instance? } to remove.",
            "type": "array",
            "items": {
              "type": "object"
            }
          },
          "otherPayments": {
            "type": "object",
            "additionalProperties": true,
            "description": "{ paymentsOnAccountMade, otherPaymentsMade } in pence: payments towards this year, for the balance due."
          }
        },
        "description": "Send only what changes. Changing an approved return takes it back to draft."
      },
      "SetSaPartnersRequest": {
        "type": "object",
        "properties": {
          "partners": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SaReturnPartner"
            }
          }
        },
        "description": "Replaces the partners and allocates the statement to them. A share a person typed over is replaced too. Changing an approved return takes it back to draft.",
        "required": [
          "partners"
        ]
      },
      "R185Kind": {
        "type": "string",
        "enum": [
          "trust_discretionary",
          "trust_non_discretionary",
          "estate",
          "settlor"
        ]
      },
      "MakeR185Request": {
        "type": "object",
        "properties": {
          "kind": {
            "allOf": [
              {
                "$ref": "#/components/schemas/R185Kind"
              }
            ]
          },
          "beneficiary": {
            "type": "string"
          },
          "shareBps": {
            "type": "integer",
            "description": "Their share of the income in basis points. Needed unless discretionary."
          },
          "paymentIndex": {
            "type": "integer",
            "description": "Which row of box 14, from 0. Needed for a discretionary statement."
          },
          "overrides": {
            "type": "object",
            "additionalProperties": true,
            "description": "A person’s own figures in pence, by the form’s box: { \"3\": 1000, \"3.tax\": 250 }."
          },
          "deceasedName": {
            "type": "string"
          },
          "dateOfDeath": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          }
        },
        "description": "A statement for a beneficiary, worked from the SA900. Not filed. A person checks and signs it.",
        "required": [
          "kind",
          "beneficiary"
        ]
      },
      "ImportSaFromWorkingPapersRequest": {
        "type": "object",
        "properties": {
          "engagementId": {
            "type": "string",
            "format": "uuid",
            "description": "A sole trader engagement of this client, with section T worked."
          }
        },
        "required": [
          "engagementId"
        ]
      },
      "SaHmrcDataSource": {
        "type": "string",
        "enum": [
          "individual_employment",
          "individual_income",
          "individual_tax",
          "individual_benefits",
          "child_benefit",
          "winter_fuel",
          "national_insurance",
          "marriage_allowance",
          "sa_account"
        ]
      },
      "SaHmrcDataOutcome": {
        "type": "string",
        "enum": [
          "ok",
          "not_found",
          "not_authorised"
        ]
      },
      "SaHmrcDataItem": {
        "type": "object",
        "properties": {
          "source": {
            "allOf": [
              {
                "$ref": "#/components/schemas/SaHmrcDataSource"
              }
            ]
          },
          "outcome": {
            "allOf": [
              {
                "$ref": "#/components/schemas/SaHmrcDataOutcome"
              }
            ]
          },
          "fetchedAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "source",
          "outcome",
          "fetchedAt"
        ]
      },
      "SaHmrcSuggestion": {
        "type": "object",
        "properties": {
          "page": {
            "type": "string"
          },
          "instance": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Which SA102, when the return already has a page for this employer."
          },
          "employerPayeReference": {
            "type": [
              "string",
              "null"
            ]
          },
          "box": {
            "type": "string"
          },
          "label": {
            "type": "string"
          },
          "source": {
            "type": "string"
          },
          "value": {
            "type": "object",
            "additionalProperties": true,
            "description": "HMRC’s figure: pence for money."
          },
          "current": {
            "type": [
              "object",
              "null"
            ],
            "additionalProperties": true,
            "description": "The figure on the return now, or null."
          }
        },
        "description": "A figure HMRC holds, with what’s on the return now. A person applies it.",
        "required": [
          "page",
          "instance",
          "employerPayeReference",
          "box",
          "label",
          "source",
          "value",
          "current"
        ]
      },
      "SaHmrcAccount": {
        "type": "object",
        "properties": {
          "totalBalancePence": {
            "type": [
              "integer",
              "null"
            ]
          },
          "totalOverduePence": {
            "type": [
              "integer",
              "null"
            ]
          },
          "totalPayablePence": {
            "type": [
              "integer",
              "null"
            ]
          },
          "totalCreditPence": {
            "type": [
              "integer",
              "null"
            ]
          },
          "earliestPayableDueDate": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31"
          }
        },
        "description": "From View Self Assessment Account, in pence.",
        "required": [
          "totalBalancePence",
          "totalOverduePence",
          "totalPayablePence",
          "totalCreditPence",
          "earliestPayableDueDate"
        ]
      },
      "SaHmrcData": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SaHmrcDataItem"
            }
          },
          "suggestions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SaHmrcSuggestion"
            }
          },
          "account": {
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/SaHmrcAccount"
              }
            ]
          },
          "note": {
            "type": "string",
            "description": "What HMRC doesn’t give, so nobody waits for it."
          }
        },
        "required": [
          "items",
          "suggestions",
          "account",
          "note"
        ]
      },
      "RefreshSaHmrcDataRequest": {
        "type": "object",
        "properties": {
          "agentAccountId": {
            "type": "string",
            "format": "uuid"
          },
          "clientFacts": {
            "type": "object",
            "additionalProperties": true,
            "description": "The browser’s facts for HMRC’s fraud prevention headers."
          }
        },
        "required": [
          "agentAccountId",
          "clientFacts"
        ]
      },
      "SaHmrcSelection": {
        "type": "object",
        "properties": {
          "box": {
            "type": "string",
            "example": "EMP1"
          },
          "employerPayeReference": {
            "type": [
              "string",
              "null"
            ],
            "description": "For an SA102: the employer."
          }
        },
        "required": [
          "box"
        ]
      },
      "ApplySaHmrcDataRequest": {
        "type": "object",
        "properties": {
          "selections": {
            "description": "The figures from what HMRC holds to put on the return.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SaHmrcSelection"
            }
          }
        },
        "required": [
          "selections"
        ]
      },
      "SaNoteRequest": {
        "type": "object",
        "properties": {
          "note": {
            "type": "string",
            "maxLength": 2000
          }
        }
      },
      "RaiseSaReviewPointRequest": {
        "type": "object",
        "properties": {
          "text": {
            "type": "string",
            "minLength": 1,
            "maxLength": 2000
          },
          "boxKey": {
            "type": "string",
            "description": "The box it’s about, such as sa102.0.EMP1."
          }
        },
        "required": [
          "text"
        ]
      },
      "ApproveSaReturnRequest": {
        "type": "object",
        "properties": {
          "returnHash": {
            "type": "string",
            "description": "The hash from the return you reviewed: refused if the figures have moved since."
          },
          "note": {
            "type": "string",
            "maxLength": 2000
          }
        },
        "required": [
          "returnHash"
        ]
      },
      "RecordSaClientApprovalRequest": {
        "type": "object",
        "properties": {
          "approvedOn": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "note": {
            "type": "string",
            "maxLength": 2000,
            "description": "How they confirmed, such as an email."
          },
          "returnHash": {
            "type": "string"
          }
        },
        "description": "HMRC requires the client to confirm in writing that the return they were sent is correct and complete, before an agent files it.",
        "required": [
          "approvedOn",
          "returnHash"
        ]
      },
      "SubmitSaReturnRequest": {
        "type": "object",
        "properties": {
          "returnHash": {
            "type": "string"
          },
          "agentAccountId": {
            "type": "string",
            "format": "uuid"
          },
          "declaration": {
            "type": "object",
            "additionalProperties": true,
            "description": "{ accepted: true, version }: the agent’s declaration HMRC requires."
          }
        },
        "required": [
          "returnHash",
          "agentAccountId",
          "declaration"
        ]
      },
      "SaAiMessageRole": {
        "type": "string",
        "enum": [
          "person",
          "assistant"
        ]
      },
      "SaAiMessage": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "role": {
            "allOf": [
              {
                "$ref": "#/components/schemas/SaAiMessageRole"
              }
            ]
          },
          "text": {
            "type": "string"
          },
          "outcome": {
            "type": [
              "object",
              "null"
            ],
            "additionalProperties": true,
            "description": "On an assistant’s turn: { applied, cleared, refused, answers, stillNeeded, tokens }."
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "role",
          "text",
          "outcome",
          "createdAt"
        ]
      },
      "SaDocumentStatus": {
        "type": "string",
        "enum": [
          "pending_upload",
          "pending_scan",
          "available",
          "rejected"
        ]
      },
      "SaDocumentReadingStatus": {
        "type": "string",
        "enum": [
          "not_read",
          "read",
          "failed"
        ]
      },
      "SaDocument": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "fileName": {
            "type": "string"
          },
          "contentType": {
            "type": "string"
          },
          "sizeBytes": {
            "type": "integer"
          },
          "status": {
            "allOf": [
              {
                "$ref": "#/components/schemas/SaDocumentStatus"
              }
            ]
          },
          "rejectedReason": {
            "type": [
              "string",
              "null"
            ]
          },
          "readingStatus": {
            "allOf": [
              {
                "$ref": "#/components/schemas/SaDocumentReadingStatus"
              }
            ]
          },
          "reading": {
            "type": [
              "object",
              "null"
            ],
            "additionalProperties": true,
            "description": "{ documentType, taxYearShown, readings, warnings }."
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "fileName",
          "contentType",
          "sizeBytes",
          "status",
          "rejectedReason",
          "readingStatus",
          "reading",
          "createdAt"
        ]
      },
      "SaAiPhase": {
        "type": "string",
        "enum": [
          "questions",
          "complete",
          "change"
        ],
        "description": "What the next turn does: finds out what’s needed, fills the boxes, or acts on a request."
      },
      "SaAiEstimate": {
        "type": "object",
        "properties": {
          "tokens": {
            "type": "integer",
            "description": "Tolvi AI tokens, about."
          },
          "affordable": {
            "type": "boolean"
          },
          "reason": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "tokens",
          "affordable",
          "reason"
        ]
      },
      "SaAiState": {
        "type": "object",
        "properties": {
          "available": {
            "type": "boolean",
            "description": "Whether the firm has AI Mode on."
          },
          "unavailableReason": {
            "type": [
              "string",
              "null"
            ]
          },
          "messages": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SaAiMessage"
            }
          },
          "documents": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SaDocument"
            }
          },
          "plan": {
            "$ref": "#/components/schemas/SaPlan"
          },
          "phase": {
            "description": "What the next turn does: finds out what’s needed, fills the boxes, or acts on a request.",
            "allOf": [
              {
                "$ref": "#/components/schemas/SaAiPhase"
              }
            ]
          },
          "estimate": {
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/SaAiEstimate"
              }
            ]
          }
        },
        "description": "AI Mode on a return: the conversation, the documents, and what it would cost to carry on.",
        "required": [
          "available",
          "unavailableReason",
          "messages",
          "documents",
          "plan",
          "phase",
          "estimate"
        ]
      },
      "SendSaAiMessageRequest": {
        "type": "object",
        "properties": {
          "text": {
            "type": "string",
            "minLength": 1,
            "maxLength": 4000,
            "description": "What you want to tell or ask. National Insurance numbers, UTRs and bank details are removed before it’s stored or sent."
          }
        },
        "required": [
          "text"
        ]
      },
      "SaAiTurn": {
        "type": "object",
        "properties": {
          "available": {
            "type": "boolean",
            "description": "Whether the firm has AI Mode on."
          },
          "unavailableReason": {
            "type": [
              "string",
              "null"
            ]
          },
          "messages": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SaAiMessage"
            }
          },
          "documents": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SaDocument"
            }
          },
          "plan": {
            "$ref": "#/components/schemas/SaPlan"
          },
          "phase": {
            "description": "What the next turn does: finds out what’s needed, fills the boxes, or acts on a request.",
            "allOf": [
              {
                "$ref": "#/components/schemas/SaAiPhase"
              }
            ]
          },
          "estimate": {
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/SaAiEstimate"
              }
            ]
          },
          "reply": {
            "$ref": "#/components/schemas/SaAiMessage"
          }
        },
        "description": "One turn of AI Mode. Every figure was read from the evidence it cites by Tolvi, not the model.",
        "required": [
          "available",
          "unavailableReason",
          "messages",
          "documents",
          "plan",
          "phase",
          "estimate",
          "reply"
        ]
      },
      "ConfirmSaAiFiguresRequest": {
        "type": "object",
        "properties": {
          "boxKeys": {
            "description": "Boxes you have checked, keyed sa102.0.EMP1.",
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        },
        "required": [
          "boxKeys"
        ]
      },
      "CreateSaDocumentRequest": {
        "type": "object",
        "properties": {
          "fileName": {
            "type": "string",
            "minLength": 1,
            "maxLength": 200,
            "example": "P60 2026.pdf"
          },
          "contentType": {
            "type": "string",
            "example": "application/pdf"
          },
          "sizeBytes": {
            "type": "integer"
          }
        },
        "required": [
          "fileName",
          "contentType",
          "sizeBytes"
        ]
      },
      "SaDocumentUpload": {
        "type": "object",
        "properties": {
          "document": {
            "$ref": "#/components/schemas/SaDocument"
          },
          "upload": {
            "type": "object",
            "additionalProperties": true,
            "description": "{ url, headers, expiresAt }: PUT the file here."
          }
        },
        "required": [
          "document",
          "upload"
        ]
      },
      "SaCredentialStatus": {
        "type": "string",
        "enum": [
          "not_saved",
          "saved",
          "needs_update"
        ]
      },
      "SaConnectionStatus": {
        "type": "string",
        "enum": [
          "not_connected",
          "connected",
          "needs_reconnect"
        ]
      },
      "SaAgentAccount": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "credentialStatus": {
            "allOf": [
              {
                "$ref": "#/components/schemas/SaCredentialStatus"
              }
            ]
          },
          "userIdHint": {
            "type": [
              "string",
              "null"
            ],
            "description": "The last characters of the user ID, to tell accounts apart."
          },
          "lastUsedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "connectionStatus": {
            "allOf": [
              {
                "$ref": "#/components/schemas/SaConnectionStatus"
              }
            ]
          },
          "grantExpiresAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "HMRC’s authority ends 18 months after it was given."
          },
          "reconnectSoon": {
            "type": "boolean"
          }
        },
        "description": "A named HMRC agent account. Its sign-in and HMRC’s grant are never returned.",
        "required": [
          "id",
          "name",
          "credentialStatus",
          "userIdHint",
          "lastUsedAt",
          "connectionStatus",
          "grantExpiresAt",
          "reconnectSoon"
        ]
      },
      "SaAgentAccountList": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SaAgentAccount"
            }
          },
          "hmrcAvailable": {
            "type": "boolean",
            "description": "Whether Tolvi can reach HMRC on this deployment."
          },
          "canStoreCredentials": {
            "type": "boolean",
            "description": "Whether this deployment can store sign-ins (encryption is set up)."
          }
        },
        "required": [
          "items",
          "hmrcAvailable",
          "canStoreCredentials"
        ]
      },
      "CreateSaAgentAccountRequest": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 80,
            "example": "Leeds office"
          }
        },
        "required": [
          "name"
        ]
      },
      "SaveSaCredentialsRequest": {
        "type": "object",
        "properties": {
          "userId": {
            "type": "string",
            "description": "The HMRC online services user ID."
          },
          "password": {
            "type": "string",
            "format": "password"
          }
        },
        "description": "Stored encrypted, used only when someone allowed to file files a return, and never returned by any route.",
        "required": [
          "userId",
          "password"
        ]
      },
      "SaAuthorizeUrl": {
        "type": "object",
        "properties": {
          "url": {
            "type": "string"
          }
        },
        "required": [
          "url"
        ]
      },
      "SaHmrcCallbackRequest": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string"
          },
          "state": {
            "type": "string"
          }
        },
        "required": [
          "code",
          "state"
        ]
      },
      "FilingProduct": {
        "type": "string",
        "enum": [
          "self_assessment",
          "corporation_tax",
          "companies_house"
        ]
      },
      "FilingReadyItem": {
        "type": "object",
        "properties": {
          "product": {
            "allOf": [
              {
                "$ref": "#/components/schemas/FilingProduct"
              }
            ]
          },
          "returnId": {
            "type": "string",
            "format": "uuid"
          },
          "clientId": {
            "type": "string",
            "format": "uuid"
          },
          "clientName": {
            "type": "string"
          },
          "label": {
            "type": "string"
          },
          "figuresHash": {
            "type": "string"
          },
          "canFile": {
            "type": "boolean",
            "description": "Whether this can go in a batch today."
          },
          "reason": {
            "type": [
              "string",
              "null"
            ]
          },
          "filingOpen": {
            "type": "boolean"
          },
          "opensSoonMessage": {
            "type": [
              "string",
              "null"
            ],
            "description": "Shown instead of a way to file while the switch is off."
          }
        },
        "required": [
          "product",
          "returnId",
          "clientId",
          "clientName",
          "label",
          "figuresHash",
          "canFile",
          "reason",
          "filingOpen",
          "opensSoonMessage"
        ]
      },
      "FilingProductState": {
        "type": "object",
        "properties": {
          "product": {
            "allOf": [
              {
                "$ref": "#/components/schemas/FilingProduct"
              }
            ]
          },
          "filingOpen": {
            "type": "boolean"
          },
          "opensSoonMessage": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "product",
          "filingOpen",
          "opensSoonMessage"
        ]
      },
      "FilingReadyList": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/FilingReadyItem"
            }
          },
          "products": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/FilingProductState"
            }
          },
          "declarations": {
            "type": "object",
            "additionalProperties": true,
            "description": "The declarations a person accepts to start a batch, by product."
          }
        },
        "required": [
          "items",
          "products",
          "declarations"
        ]
      },
      "FilingBatchStatus": {
        "type": "string",
        "enum": [
          "ready",
          "running",
          "finished"
        ]
      },
      "FilingItemStatus": {
        "type": "string",
        "enum": [
          "waiting",
          "sending",
          "filed",
          "with_authority",
          "test_accepted",
          "refused",
          "rejected",
          "no_answer"
        ]
      },
      "FilingBatchItem": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "position": {
            "type": "integer"
          },
          "product": {
            "allOf": [
              {
                "$ref": "#/components/schemas/FilingProduct"
              }
            ]
          },
          "returnId": {
            "type": "string",
            "format": "uuid"
          },
          "clientName": {
            "type": "string"
          },
          "label": {
            "type": "string"
          },
          "status": {
            "allOf": [
              {
                "$ref": "#/components/schemas/FilingItemStatus"
              }
            ]
          },
          "message": {
            "type": [
              "string",
              "null"
            ],
            "description": "In plain words."
          },
          "finishedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "position",
          "product",
          "returnId",
          "clientName",
          "label",
          "status",
          "message",
          "finishedAt"
        ]
      },
      "FilingBatch": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "status": {
            "allOf": [
              {
                "$ref": "#/components/schemas/FilingBatchStatus"
              }
            ]
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "startedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "finishedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/FilingBatchItem"
            }
          }
        },
        "required": [
          "id",
          "status",
          "createdAt",
          "startedAt",
          "finishedAt",
          "items"
        ]
      },
      "FilingBatchList": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/FilingBatch"
            }
          }
        },
        "required": [
          "items"
        ]
      },
      "FilingVariant": {
        "type": "string",
        "enum": [
          "full",
          "filleted"
        ]
      },
      "FilingBatchNewItem": {
        "type": "object",
        "properties": {
          "product": {
            "allOf": [
              {
                "$ref": "#/components/schemas/FilingProduct"
              }
            ]
          },
          "returnId": {
            "type": "string",
            "format": "uuid"
          },
          "figuresHash": {
            "type": "string",
            "description": "The hash you reviewed. A change since is refused."
          },
          "accountId": {
            "type": "string",
            "format": "uuid",
            "description": "The HMRC account or Companies House presenter to file with."
          },
          "variant": {
            "allOf": [
              {
                "$ref": "#/components/schemas/FilingVariant"
              }
            ]
          }
        },
        "required": [
          "product",
          "returnId",
          "figuresHash",
          "accountId"
        ]
      },
      "CreateFilingBatch": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/FilingBatchNewItem"
            }
          }
        },
        "required": [
          "items"
        ]
      },
      "StartFilingBatch": {
        "type": "object",
        "properties": {
          "declarations": {
            "type": "object",
            "additionalProperties": true,
            "description": "The declaration accepted for each product in the batch: `{ accepted: true, version }`."
          },
          "companyCodes": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            },
            "description": "Companies House company authentication codes by item id. Used once, never stored."
          }
        }
      },
      "PracticeVatSource": {
        "type": "string",
        "enum": [
          "spreadsheet",
          "typed",
          "working_papers",
          "books"
        ]
      },
      "PracticeVatStatus": {
        "type": "string",
        "enum": [
          "draft",
          "approved",
          "filing",
          "filed"
        ]
      },
      "PracticeVatReturn": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "clientId": {
            "type": "string",
            "format": "uuid"
          },
          "clientName": {
            "type": "string"
          },
          "vrn": {
            "type": "string"
          },
          "periodKey": {
            "type": "string"
          },
          "periodStart": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "periodEnd": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "boxes": {
            "type": "object",
            "additionalProperties": {
              "type": "integer"
            },
            "description": "box1 to box9, integer pence."
          },
          "source": {
            "allOf": [
              {
                "$ref": "#/components/schemas/PracticeVatSource"
              }
            ]
          },
          "sourceNote": {
            "type": [
              "string",
              "null"
            ]
          },
          "status": {
            "allOf": [
              {
                "$ref": "#/components/schemas/PracticeVatStatus"
              }
            ]
          },
          "submissionStatus": {
            "type": [
              "string",
              "null"
            ]
          },
          "receipt": {
            "type": [
              "object",
              "null"
            ],
            "additionalProperties": true
          },
          "lastError": {
            "type": [
              "string",
              "null"
            ]
          },
          "returnHash": {
            "type": "string"
          },
          "clientApprovedOn": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31"
          },
          "clientApprovalCurrent": {
            "type": "boolean"
          },
          "canSubmit": {
            "type": "boolean"
          },
          "cannotSubmitReason": {
            "type": [
              "string",
              "null"
            ]
          },
          "filingEnabled": {
            "type": "boolean"
          },
          "declaration": {
            "type": "object",
            "additionalProperties": true
          }
        },
        "required": [
          "id",
          "clientId",
          "vrn",
          "periodKey",
          "periodStart",
          "periodEnd",
          "boxes",
          "source",
          "sourceNote",
          "status",
          "submissionStatus",
          "receipt",
          "lastError",
          "returnHash",
          "clientApprovedOn",
          "clientApprovalCurrent",
          "canSubmit",
          "cannotSubmitReason",
          "filingEnabled",
          "declaration"
        ]
      },
      "PracticeVatReturnList": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PracticeVatReturn"
            }
          }
        },
        "required": [
          "items"
        ]
      },
      "SpreadsheetRows": {
        "type": "object",
        "properties": {
          "rows": {
            "type": "array",
            "items": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "description": "Label, then amount in pounds."
          }
        },
        "required": [
          "rows"
        ]
      },
      "PracticeVatSheetReading": {
        "type": "object",
        "properties": {
          "boxes": {
            "type": [
              "object",
              "null"
            ],
            "additionalProperties": {
              "type": "integer"
            }
          },
          "problems": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "ignored": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        },
        "required": [
          "boxes",
          "problems",
          "ignored"
        ]
      },
      "CreatePracticeVatReturn": {
        "type": "object",
        "properties": {
          "clientId": {
            "type": "string",
            "format": "uuid"
          },
          "vrn": {
            "type": "string",
            "description": "Left out, the VAT number on the client’s record. The return keeps the number it was prepared under."
          },
          "periodKey": {
            "type": "string",
            "description": "HMRC’s period key, from the client’s VAT account."
          },
          "periodStart": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "periodEnd": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "source": {
            "allOf": [
              {
                "$ref": "#/components/schemas/PracticeVatSource"
              }
            ]
          },
          "sourceNote": {
            "type": "string"
          },
          "rows": {
            "type": "array",
            "items": {
              "type": "array",
              "items": {
                "type": "string"
              }
            }
          },
          "boxes": {
            "type": "object",
            "additionalProperties": {
              "type": "integer"
            }
          }
        },
        "required": [
          "clientId",
          "periodKey",
          "periodStart",
          "periodEnd",
          "source"
        ]
      },
      "PracticeVatHash": {
        "type": "object",
        "properties": {
          "returnHash": {
            "type": "string"
          }
        },
        "required": [
          "returnHash"
        ]
      },
      "PracticeVatClientApproval": {
        "type": "object",
        "properties": {
          "approvedOn": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "returnHash": {
            "type": "string"
          }
        },
        "required": [
          "approvedOn",
          "returnHash"
        ]
      },
      "SubmitPracticeVat": {
        "type": "object",
        "properties": {
          "returnHash": {
            "type": "string"
          },
          "declaration": {
            "type": "object",
            "additionalProperties": true
          },
          "clientFacts": {
            "type": "object",
            "additionalProperties": true,
            "description": "The browser’s facts, for HMRC’s fraud prevention headers."
          }
        },
        "required": [
          "returnHash",
          "declaration",
          "clientFacts"
        ]
      },
      "MtdItSourceKind": {
        "type": "string",
        "enum": [
          "self_employment",
          "uk_property"
        ]
      },
      "MtdItPeriodType": {
        "type": "string",
        "enum": [
          "standard",
          "calendar"
        ]
      },
      "MtdItSource": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "clientId": {
            "type": "string",
            "format": "uuid"
          },
          "kind": {
            "allOf": [
              {
                "$ref": "#/components/schemas/MtdItSourceKind"
              }
            ]
          },
          "name": {
            "type": "string"
          },
          "hmrcBusinessId": {
            "type": [
              "string",
              "null"
            ]
          },
          "periodType": {
            "allOf": [
              {
                "$ref": "#/components/schemas/MtdItPeriodType"
              }
            ]
          },
          "ninoMask": {
            "type": [
              "string",
              "null"
            ]
          },
          "sendingEnabled": {
            "type": "boolean"
          }
        },
        "required": [
          "id",
          "clientId",
          "kind",
          "name",
          "hmrcBusinessId",
          "periodType",
          "ninoMask",
          "sendingEnabled"
        ]
      },
      "MtdItSourceList": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/MtdItSource"
            }
          }
        },
        "required": [
          "items"
        ]
      },
      "AddMtdItSource": {
        "type": "object",
        "properties": {
          "clientId": {
            "type": "string",
            "format": "uuid"
          },
          "kind": {
            "allOf": [
              {
                "$ref": "#/components/schemas/MtdItSourceKind"
              }
            ]
          },
          "name": {
            "type": "string"
          },
          "hmrcBusinessId": {
            "type": "string"
          },
          "periodType": {
            "allOf": [
              {
                "$ref": "#/components/schemas/MtdItPeriodType"
              }
            ]
          },
          "nino": {
            "type": "string",
            "description": "Sent once and held encrypted. Only a mask comes back."
          }
        },
        "required": [
          "clientId",
          "kind",
          "name"
        ]
      },
      "MtdItObligation": {
        "type": "object",
        "properties": {
          "quarter": {
            "type": "integer"
          },
          "from": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "obligationEnd": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "due": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "met": {
            "type": "boolean"
          }
        },
        "required": [
          "quarter",
          "from",
          "obligationEnd",
          "due",
          "met"
        ]
      },
      "MtdItUpdateStatus": {
        "type": "string",
        "enum": [
          "draft",
          "approved",
          "sending",
          "accepted",
          "rejected",
          "unknown"
        ]
      },
      "MtdItUpdate": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "sourceId": {
            "type": "string",
            "format": "uuid"
          },
          "taxYearEnd": {
            "type": "integer"
          },
          "periodStart": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "periodEnd": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "figures": {
            "type": "object",
            "additionalProperties": true,
            "description": "Cumulative from 6 April, integer pence by HMRC’s field names."
          },
          "origin": {
            "type": "string"
          },
          "status": {
            "allOf": [
              {
                "$ref": "#/components/schemas/MtdItUpdateStatus"
              }
            ]
          },
          "hash": {
            "type": "string"
          },
          "lastError": {
            "type": [
              "string",
              "null"
            ]
          },
          "submittedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "sourceId",
          "taxYearEnd",
          "periodStart",
          "periodEnd",
          "figures",
          "origin",
          "status",
          "hash",
          "lastError",
          "submittedAt"
        ]
      },
      "MtdItObligations": {
        "type": "object",
        "properties": {
          "source": {
            "$ref": "#/components/schemas/MtdItSource"
          },
          "taxYearEnd": {
            "type": "integer"
          },
          "workedOut": {
            "type": "boolean",
            "description": "True: from the dates and accepted updates here, not from HMRC."
          },
          "obligations": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/MtdItObligation"
            }
          },
          "updates": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/MtdItUpdate"
            }
          }
        },
        "required": [
          "source",
          "taxYearEnd",
          "workedOut",
          "obligations",
          "updates"
        ]
      },
      "MtdItSheetReading": {
        "type": "object",
        "properties": {
          "figures": {
            "type": "object",
            "additionalProperties": true
          },
          "problems": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "ignored": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        },
        "required": [
          "figures",
          "problems",
          "ignored"
        ]
      },
      "MtdItOrigin": {
        "type": "string",
        "enum": [
          "spreadsheet",
          "typed"
        ]
      },
      "SaveMtdItUpdate": {
        "type": "object",
        "properties": {
          "taxYearEnd": {
            "type": "integer"
          },
          "periodEnd": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "origin": {
            "allOf": [
              {
                "$ref": "#/components/schemas/MtdItOrigin"
              }
            ]
          },
          "rows": {
            "type": "array",
            "items": {
              "type": "array",
              "items": {
                "type": "string"
              }
            }
          },
          "figures": {
            "type": "object",
            "additionalProperties": true
          }
        },
        "required": [
          "taxYearEnd",
          "periodEnd",
          "origin"
        ]
      },
      "MtdItHash": {
        "type": "object",
        "properties": {
          "hash": {
            "type": "string"
          }
        },
        "required": [
          "hash"
        ]
      },
      "SubmitMtdItUpdate": {
        "type": "object",
        "properties": {
          "hash": {
            "type": "string"
          },
          "clientFacts": {
            "type": "object",
            "additionalProperties": true
          }
        },
        "required": [
          "hash",
          "clientFacts"
        ]
      },
      "MtdItDeclaration": {
        "type": "object",
        "properties": {
          "clientId": {
            "type": "string",
            "format": "uuid"
          },
          "taxYearEnd": {
            "type": "integer"
          },
          "due": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "stage": {
            "type": "string"
          },
          "calculationId": {
            "type": [
              "string",
              "null"
            ]
          },
          "calculation": {
            "type": [
              "object",
              "null"
            ],
            "additionalProperties": true
          },
          "errors": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "clientConfirmedOn": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31"
          },
          "declaredAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "sendingEnabled": {
            "type": "boolean"
          },
          "confirmation": {
            "type": "object",
            "additionalProperties": true
          }
        },
        "required": [
          "clientId",
          "taxYearEnd",
          "due",
          "stage",
          "calculationId",
          "calculation",
          "errors",
          "clientConfirmedOn",
          "declaredAt",
          "sendingEnabled",
          "confirmation"
        ]
      },
      "MtdItDeclarationStep": {
        "type": "object",
        "properties": {
          "clientId": {
            "type": "string",
            "format": "uuid"
          },
          "taxYearEnd": {
            "type": "integer"
          },
          "calculationId": {
            "type": "string"
          },
          "approvedOn": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "confirmation": {
            "type": "object",
            "additionalProperties": true
          },
          "clientFacts": {
            "type": "object",
            "additionalProperties": true
          }
        },
        "required": [
          "clientId",
          "taxYearEnd"
        ]
      },
      "TrustRegistrationDue": {
        "type": "object",
        "properties": {
          "kind": {
            "type": "string"
          },
          "due": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "label": {
            "type": "string"
          },
          "taxYearEnd": {
            "type": "integer"
          }
        },
        "required": [
          "kind",
          "due",
          "label"
        ]
      },
      "TrustRegistration": {
        "type": "object",
        "properties": {
          "clientId": {
            "type": "string",
            "format": "uuid"
          },
          "reference": {
            "type": [
              "string",
              "null"
            ],
            "description": "The UTR or Unique Reference Number HMRC gave."
          },
          "registeredOn": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31"
          },
          "taxable": {
            "type": "boolean"
          },
          "liableTaxYearEnds": {
            "type": "array",
            "items": {
              "type": "number"
            }
          },
          "declaredTaxYearEnds": {
            "type": "array",
            "items": {
              "type": "number"
            }
          },
          "changeAwareOn": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31"
          },
          "due": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TrustRegistrationDue"
            }
          },
          "remindersOn": {
            "type": "boolean"
          }
        },
        "required": [
          "clientId",
          "reference",
          "registeredOn",
          "taxable",
          "liableTaxYearEnds",
          "declaredTaxYearEnds",
          "changeAwareOn",
          "due",
          "remindersOn"
        ]
      },
      "EngagementStatus": {
        "type": "string",
        "enum": [
          "not_started",
          "in_progress",
          "submitted",
          "returned",
          "complete"
        ]
      },
      "WorkScope": {
        "type": "string",
        "enum": [
          "everyone",
          "mine"
        ]
      },
      "WorkSort": {
        "type": "string",
        "enum": [
          "due",
          "client",
          "ye",
          "rounds"
        ]
      },
      "WorkView": {
        "type": "string",
        "enum": [
          "mine",
          "review",
          "returned",
          "due30",
          "overdue",
          "changed",
          "open",
          "all",
          "todo",
          "later",
          "stuck",
          "at_risk",
          "unassigned"
        ]
      },
      "SyncState": {
        "type": "string",
        "enum": [
          "in_sync",
          "changed",
          "expired_token",
          "error",
          "never_synced",
          "manual"
        ]
      },
      "RiskLevel": {
        "type": "string",
        "enum": [
          "standard",
          "high"
        ]
      },
      "WorkRow": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "Engagement id."
          },
          "clientId": {
            "type": "string",
            "format": "uuid"
          },
          "clientName": {
            "type": "string"
          },
          "entityType": {
            "allOf": [
              {
                "$ref": "#/components/schemas/EntityType"
              }
            ]
          },
          "periodStart": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "periodEnd": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "dueDate": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31",
            "description": "Filing deadline."
          },
          "daysLeft": {
            "type": "integer",
            "description": "Days from today (Europe/London) to the deadline; negative when overdue."
          },
          "provisional": {
            "type": "boolean",
            "description": "The deadline is for a tax year and the return may need provisional figures."
          },
          "status": {
            "allOf": [
              {
                "$ref": "#/components/schemas/EngagementStatus"
              }
            ]
          },
          "stageIndex": {
            "type": "integer",
            "minimum": 0
          },
          "stageName": {
            "type": "string"
          },
          "stageCount": {
            "type": "integer",
            "minimum": 1
          },
          "workflowName": {
            "type": "string"
          },
          "currentActorId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid",
            "description": "Who acts next."
          },
          "preparerId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "reviewerId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "managerId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "partnerId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "rounds": {
            "type": "integer",
            "minimum": 0,
            "description": "Review rounds (returns to the preparer)."
          },
          "openPoints": {
            "type": "integer",
            "minimum": 0,
            "description": "Open review points."
          },
          "syncState": {
            "allOf": [
              {
                "$ref": "#/components/schemas/SyncState"
              }
            ]
          },
          "software": {
            "allOf": [
              {
                "$ref": "#/components/schemas/Software"
              }
            ]
          },
          "lastSyncedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "risk": {
            "allOf": [
              {
                "$ref": "#/components/schemas/RiskLevel"
              }
            ]
          },
          "filedOn": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31",
            "description": "When the accounts were filed (recorded by a person)."
          }
        },
        "description": "One engagement in the work queue.",
        "required": [
          "id",
          "clientId",
          "clientName",
          "entityType",
          "periodStart",
          "periodEnd",
          "dueDate",
          "daysLeft",
          "provisional",
          "status",
          "stageIndex",
          "stageName",
          "stageCount",
          "workflowName",
          "currentActorId",
          "preparerId",
          "reviewerId",
          "managerId",
          "partnerId",
          "rounds",
          "openPoints",
          "syncState",
          "software",
          "lastSyncedAt",
          "risk",
          "filedOn"
        ]
      },
      "WorkPage": {
        "type": "object",
        "properties": {
          "rows": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/WorkRow"
            }
          },
          "nextCursor": {
            "type": [
              "string",
              "null"
            ],
            "description": "Opaque cursor for the next page (pass as `cursor`); null on the last page."
          },
          "pageSize": {
            "type": "integer",
            "minimum": 1,
            "maximum": 100,
            "description": "The page size that was used."
          }
        },
        "required": [
          "rows",
          "nextCursor",
          "pageSize"
        ]
      },
      "WorkViewCounts": {
        "type": "object",
        "properties": {
          "mine": {
            "type": "integer"
          },
          "review": {
            "type": "integer"
          },
          "returned": {
            "type": "integer"
          },
          "due30": {
            "type": "integer"
          },
          "overdue": {
            "type": "integer"
          },
          "changed": {
            "type": "integer"
          },
          "open": {
            "type": "integer"
          },
          "all": {
            "type": "integer"
          },
          "todo": {
            "type": "integer",
            "description": "Your turn, due within 120 days."
          },
          "later": {
            "type": "integer",
            "description": "Your turn, due in more than 120 days."
          },
          "stuck": {
            "type": "integer",
            "description": "In review for more than 14 days."
          },
          "at_risk": {
            "type": "integer",
            "description": "At risk: not yet overdue, but likely to miss the deadline at its current stage. Due within 45 days and not started, 30 days preparing, 21 days returned or 14 days in review."
          },
          "unassigned": {
            "type": "integer",
            "description": "Open engagements with no preparer (nobody’s To do until assigned)."
          }
        },
        "description": "Engagements in each saved view.",
        "required": [
          "mine",
          "review",
          "returned",
          "due30",
          "overdue",
          "changed",
          "open",
          "all",
          "todo",
          "later",
          "stuck",
          "at_risk",
          "unassigned"
        ]
      },
      "WorkKpis": {
        "type": "object",
        "properties": {
          "due30": {
            "type": "integer"
          },
          "overdue": {
            "type": "integer"
          },
          "awaitingReview": {
            "type": "integer"
          },
          "awaitingMyReview": {
            "type": "integer"
          },
          "changed": {
            "type": "integer"
          },
          "avgRounds": {
            "type": "number",
            "description": "Average review rounds on complete engagements, to 2 dp."
          },
          "firstTimeRightPct": {
            "type": "integer",
            "minimum": 0,
            "maximum": 100
          }
        },
        "required": [
          "due30",
          "overdue",
          "awaitingReview",
          "awaitingMyReview",
          "changed",
          "avgRounds",
          "firstTimeRightPct"
        ]
      },
      "WorkCounts": {
        "type": "object",
        "properties": {
          "views": {
            "$ref": "#/components/schemas/WorkViewCounts"
          },
          "kpis": {
            "$ref": "#/components/schemas/WorkKpis"
          },
          "total": {
            "type": "integer",
            "description": "All engagements in the firm, ignoring filters."
          }
        },
        "required": [
          "views",
          "kpis",
          "total"
        ]
      },
      "WorkGroupBy": {
        "type": "string",
        "enum": [
          "status",
          "due",
          "actor"
        ]
      },
      "WorkGroup": {
        "type": "object",
        "properties": {
          "key": {
            "type": [
              "string",
              "null"
            ],
            "description": "A status, a deadline (YYYY-MM-DD) or a person id (null: nobody)."
          },
          "count": {
            "type": "integer"
          }
        },
        "required": [
          "key",
          "count"
        ]
      },
      "WorkGroups": {
        "type": "object",
        "properties": {
          "groupBy": {
            "allOf": [
              {
                "$ref": "#/components/schemas/WorkGroupBy"
              }
            ]
          },
          "groups": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/WorkGroup"
            }
          },
          "total": {
            "type": "integer"
          }
        },
        "required": [
          "groupBy",
          "groups",
          "total"
        ]
      },
      "BringForward": {
        "type": "object",
        "properties": {
          "priorYearFigures": {
            "type": "boolean",
            "description": "Last year’s final TB (draft + posted journals) as this year’s comparatives, kept when this year’s TB is imported."
          },
          "mappings": {
            "type": "boolean",
            "description": "Last year’s account mappings, applied when the trial balance is imported."
          },
          "fixedAssets": {
            "type": "boolean",
            "description": "The fixed asset register: closing cost and depreciation as opening balances, disposed assets left out."
          },
          "taxBroughtForward": {
            "type": "boolean",
            "description": "Main and special rate pool WDVs and trading losses carried forward."
          },
          "notes": {
            "type": "boolean",
            "description": "Last year’s variance notes, as hints on the lead schedules (never as this year’s explanations)."
          },
          "clientSteps": {
            "type": "boolean",
            "description": "The client’s own checklist steps, added to the firm’s checklists."
          }
        },
        "description": "What to carry over from the client’s previous engagement (the year-end roll forward). Each defaults to true."
      },
      "StartEngagements": {
        "type": "object",
        "properties": {
          "engagementIds": {
            "minItems": 1,
            "maxItems": 500,
            "type": "array",
            "items": {
              "type": "string",
              "format": "uuid"
            }
          },
          "workflowId": {
            "type": "string",
            "description": "Workflow template id; default: the client’s, else the firm default for the entity type."
          },
          "preparerId": {
            "type": "string",
            "format": "uuid"
          },
          "reviewerId": {
            "type": "string",
            "format": "uuid"
          },
          "managerId": {
            "type": "string",
            "format": "uuid"
          },
          "partnerId": {
            "type": "string",
            "format": "uuid"
          },
          "pullTrialBalance": {
            "type": "boolean",
            "description": "Pull each started engagement’s TB from its client’s bookkeeping connection (reported back in tbPulls)."
          },
          "bringForward": {
            "$ref": "#/components/schemas/BringForward"
          }
        },
        "required": [
          "engagementIds"
        ]
      },
      "TbPullOutcomeKind": {
        "type": "string",
        "enum": [
          "pulled",
          "queued",
          "not_connected",
          "failed"
        ],
        "description": "pulled: a new TB version from the books; queued: being pulled in the background (large batches); not_connected: no usable connection; failed: see message."
      },
      "TbPullOutcome": {
        "type": "object",
        "properties": {
          "engagementId": {
            "type": "string",
            "format": "uuid"
          },
          "outcome": {
            "description": "pulled: a new TB version from the books; queued: being pulled in the background (large batches); not_connected: no usable connection; failed: see message.",
            "allOf": [
              {
                "$ref": "#/components/schemas/TbPullOutcomeKind"
              }
            ]
          },
          "message": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "engagementId",
          "outcome",
          "message"
        ]
      },
      "BroughtForward": {
        "type": "object",
        "properties": {
          "mappings": {
            "type": "integer"
          },
          "notes": {
            "type": "integer",
            "description": "Variance notes brought forward as hints."
          },
          "clientSteps": {
            "type": "integer"
          },
          "priorYearAccounts": {
            "type": "integer",
            "description": "Accounts in last year’s final TB brought forward as comparatives."
          },
          "fixedAssets": {
            "type": "integer",
            "description": "Fixed assets brought forward with their closing balances."
          },
          "taxBroughtForward": {
            "type": "integer",
            "description": "Engagements whose pools and losses carried forward were brought forward."
          }
        },
        "description": "What was carried over, totalled across the engagements started.",
        "required": [
          "mappings",
          "notes",
          "clientSteps",
          "priorYearAccounts",
          "fixedAssets",
          "taxBroughtForward"
        ]
      },
      "StartResult": {
        "type": "object",
        "properties": {
          "started": {
            "type": "integer"
          },
          "alreadyStarted": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "uuid"
            }
          },
          "notFound": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "uuid"
            }
          },
          "blocked": {
            "type": [
              "string",
              "null"
            ],
            "description": "Why the rest of a bulk start stopped (billing)."
          },
          "trialBalancePulled": {
            "type": "boolean",
            "description": "pullTrialBalance was asked for and every started engagement with a connection was pulled (or queued) without failure."
          },
          "tbPulls": {
            "description": "Per started engagement, when pullTrialBalance was asked for.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TbPullOutcome"
            }
          },
          "broughtForward": {
            "$ref": "#/components/schemas/BroughtForward"
          },
          "notified": {
            "type": "integer",
            "description": "Team members told in-app that they were added (the person starting is never told)."
          }
        },
        "required": [
          "started",
          "alreadyStarted",
          "notFound",
          "blocked",
          "trialBalancePulled",
          "tbPulls",
          "broughtForward",
          "notified"
        ]
      },
      "FiledEntry": {
        "type": "object",
        "properties": {
          "engagementId": {
            "type": "string",
            "format": "uuid"
          },
          "filedOn": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          }
        },
        "required": [
          "engagementId",
          "filedOn"
        ]
      },
      "MarkFiled": {
        "type": "object",
        "properties": {
          "filed": {
            "minItems": 1,
            "maxItems": 500,
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/FiledEntry"
            }
          }
        },
        "required": [
          "filed"
        ]
      },
      "MarkFiledResult": {
        "type": "object",
        "properties": {
          "updated": {
            "type": "integer"
          }
        },
        "required": [
          "updated"
        ]
      },
      "Person": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "initials": {
            "type": "string",
            "example": "SP"
          },
          "role": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/StaffRole"
              },
              {
                "type": "null"
              }
            ]
          },
          "openInRole": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 0,
            "description": "Open engagements this person holds in their own role (as preparer, reviewer, manager or partner). Null for practice admin staff."
          },
          "capacity": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 0,
            "description": "Their role’s capacity (open jobs at once, from the firm’s settings); null for no limit."
          }
        },
        "required": [
          "id",
          "name",
          "initials",
          "role"
        ]
      },
      "AssignRequest": {
        "type": "object",
        "properties": {
          "engagementIds": {
            "minItems": 1,
            "maxItems": 500,
            "type": "array",
            "items": {
              "type": "string",
              "format": "uuid"
            }
          },
          "preparerId": {
            "type": "string",
            "format": "uuid"
          },
          "reviewerId": {
            "type": "string",
            "format": "uuid"
          },
          "managerId": {
            "type": "string",
            "format": "uuid"
          },
          "partnerId": {
            "type": "string",
            "format": "uuid"
          }
        },
        "description": "Give at least one of preparerId, reviewerId, managerId or partnerId.",
        "required": [
          "engagementIds"
        ]
      },
      "AssignResult": {
        "type": "object",
        "properties": {
          "updated": {
            "type": "integer",
            "description": "Engagements updated (ids from other firms are ignored)."
          }
        },
        "required": [
          "updated"
        ]
      },
      "TimelineStepState": {
        "type": "string",
        "enum": [
          "done",
          "now",
          "todo"
        ]
      },
      "WorkTimelineStep": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string"
          },
          "role": {
            "allOf": [
              {
                "$ref": "#/components/schemas/StaffRole"
              }
            ]
          },
          "assigneeId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "state": {
            "allOf": [
              {
                "$ref": "#/components/schemas/TimelineStepState"
              }
            ]
          },
          "mustDiffer": {
            "type": "boolean",
            "description": "The assignee must differ from the previous stage’s."
          }
        },
        "required": [
          "name",
          "role",
          "assigneeId",
          "state",
          "mustDiffer"
        ]
      },
      "WorkDetail": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "Engagement id."
          },
          "clientId": {
            "type": "string",
            "format": "uuid"
          },
          "clientName": {
            "type": "string"
          },
          "entityType": {
            "allOf": [
              {
                "$ref": "#/components/schemas/EntityType"
              }
            ]
          },
          "periodStart": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "periodEnd": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "dueDate": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31",
            "description": "Filing deadline."
          },
          "daysLeft": {
            "type": "integer",
            "description": "Days from today (Europe/London) to the deadline; negative when overdue."
          },
          "provisional": {
            "type": "boolean",
            "description": "The deadline is for a tax year and the return may need provisional figures."
          },
          "status": {
            "allOf": [
              {
                "$ref": "#/components/schemas/EngagementStatus"
              }
            ]
          },
          "stageIndex": {
            "type": "integer",
            "minimum": 0
          },
          "stageName": {
            "type": "string"
          },
          "stageCount": {
            "type": "integer",
            "minimum": 1
          },
          "workflowName": {
            "type": "string"
          },
          "currentActorId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid",
            "description": "Who acts next."
          },
          "preparerId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "reviewerId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "managerId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "partnerId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "rounds": {
            "type": "integer",
            "minimum": 0,
            "description": "Review rounds (returns to the preparer)."
          },
          "openPoints": {
            "type": "integer",
            "minimum": 0,
            "description": "Open review points."
          },
          "syncState": {
            "allOf": [
              {
                "$ref": "#/components/schemas/SyncState"
              }
            ]
          },
          "software": {
            "allOf": [
              {
                "$ref": "#/components/schemas/Software"
              }
            ]
          },
          "lastSyncedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "risk": {
            "allOf": [
              {
                "$ref": "#/components/schemas/RiskLevel"
              }
            ]
          },
          "filedOn": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31",
            "description": "When the accounts were filed (recorded by a person)."
          },
          "workflowTemplateId": {
            "type": "string"
          },
          "timeline": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/WorkTimelineStep"
            }
          }
        },
        "required": [
          "id",
          "clientId",
          "clientName",
          "entityType",
          "periodStart",
          "periodEnd",
          "dueDate",
          "daysLeft",
          "provisional",
          "status",
          "stageIndex",
          "stageName",
          "stageCount",
          "workflowName",
          "currentActorId",
          "preparerId",
          "reviewerId",
          "managerId",
          "partnerId",
          "rounds",
          "openPoints",
          "syncState",
          "software",
          "lastSyncedAt",
          "risk",
          "filedOn",
          "workflowTemplateId",
          "timeline"
        ]
      },
      "InvitationStatus": {
        "type": "string",
        "enum": [
          "pending",
          "accepted",
          "revoked",
          "expired"
        ]
      },
      "Invitation": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "email": {
            "type": "string",
            "format": "email"
          },
          "role": {
            "allOf": [
              {
                "$ref": "#/components/schemas/MembershipRole"
              }
            ]
          },
          "staffRole": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/StaffRole"
              },
              {
                "type": "null"
              }
            ]
          },
          "status": {
            "allOf": [
              {
                "$ref": "#/components/schemas/InvitationStatus"
              }
            ]
          },
          "expiresAt": {
            "type": "string",
            "format": "date-time"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "email",
          "role",
          "staffRole",
          "status",
          "expiresAt",
          "createdAt"
        ]
      },
      "CreateInvitationRequest": {
        "type": "object",
        "properties": {
          "email": {
            "type": "string",
            "format": "email",
            "maxLength": 254
          },
          "staffRole": {
            "allOf": [
              {
                "$ref": "#/components/schemas/StaffRole"
              }
            ]
          },
          "role": {
            "default": "staff",
            "allOf": [
              {
                "$ref": "#/components/schemas/MembershipRole"
              }
            ]
          }
        },
        "required": [
          "email",
          "staffRole"
        ]
      },
      "AcceptInvitationRequest": {
        "type": "object",
        "properties": {
          "token": {
            "type": "string",
            "pattern": "^[A-Za-z0-9_-]{43}$",
            "description": "The token from the invitation email."
          }
        },
        "required": [
          "token"
        ]
      },
      "AcceptInvitationResult": {
        "type": "object",
        "properties": {
          "firmId": {
            "type": "string",
            "format": "uuid"
          },
          "firmName": {
            "type": "string"
          },
          "authOrgId": {
            "type": [
              "string",
              "null"
            ],
            "description": "The firm’s identity-provider organisation, if it has one. Sign in through it to open the firm."
          }
        },
        "required": [
          "firmId",
          "firmName"
        ]
      },
      "InvitationPreview": {
        "type": "object",
        "properties": {
          "status": {
            "allOf": [
              {
                "$ref": "#/components/schemas/InvitationStatus"
              }
            ]
          },
          "firmName": {
            "type": "string"
          },
          "role": {
            "allOf": [
              {
                "$ref": "#/components/schemas/MembershipRole"
              }
            ]
          },
          "staffRole": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/StaffRole"
              },
              {
                "type": "null"
              }
            ]
          },
          "invitedByName": {
            "type": [
              "string",
              "null"
            ]
          },
          "emailHint": {
            "type": "string",
            "description": "The invited address, mostly hidden: “s•••@hartwell.co.uk”. Sign in with the full address."
          },
          "expiresAt": {
            "type": "string",
            "format": "date-time"
          },
          "tenantKind": {
            "description": "Which kind of tenant it joins: a practice opens in the Tolvi web app, a business in Tolvi Books.",
            "allOf": [
              {
                "$ref": "#/components/schemas/TenantKind"
              }
            ]
          },
          "appUrl": {
            "type": "string",
            "description": "The address of the Tolvi app this invitation opens in (server configuration)."
          }
        },
        "description": "What an invitation link says before anyone signs in: the firm, who sent it, the role and whether it can still be used.",
        "required": [
          "status",
          "firmName",
          "role",
          "staffRole",
          "invitedByName",
          "emailHint",
          "expiresAt"
        ]
      },
      "PendingInvitation": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "Accept it with POST /invitations/{id}/accept-for-me."
          },
          "firmName": {
            "type": "string"
          },
          "role": {
            "allOf": [
              {
                "$ref": "#/components/schemas/MembershipRole"
              }
            ]
          },
          "staffRole": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/StaffRole"
              },
              {
                "type": "null"
              }
            ]
          },
          "invitedByName": {
            "type": [
              "string",
              "null"
            ]
          },
          "expiresAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "description": "An invitation waiting for the signed-in person, matched on their verified email address.",
        "required": [
          "id",
          "firmName",
          "role",
          "staffRole",
          "invitedByName",
          "expiresAt"
        ]
      },
      "SignUpRequest": {
        "type": "object",
        "properties": {
          "firmName": {
            "type": "string",
            "minLength": 1,
            "maxLength": 200,
            "example": "Alder & Co"
          },
          "email": {
            "type": "string",
            "format": "email",
            "maxLength": 254,
            "description": "The founder’s work email. They become the firm’s owner."
          },
          "marketingConsent": {
            "type": "boolean",
            "default": false,
            "description": "The founder opted in to Tolvi marketing email (an unticked box on the form; MARKETING_CONSENT_TEXT). Recorded with the wording version and time. Trial emails about the account are sent either way."
          }
        },
        "required": [
          "firmName",
          "email"
        ]
      },
      "SignUpResult": {
        "type": "object",
        "properties": {
          "email": {
            "type": "string",
            "format": "email",
            "description": "Where the link to finish signing up was sent."
          }
        },
        "required": [
          "email"
        ]
      },
      "CredentialKind": {
        "type": "string",
        "enum": [
          "personal",
          "client"
        ]
      },
      "Scope": {
        "type": "string",
        "enum": [
          "work:read",
          "clients:read",
          "clients:write",
          "engagements:read",
          "engagements:write",
          "review:write",
          "integrations:manage",
          "settings:read",
          "settings:admin",
          "webhooks:manage",
          "meetings:read",
          "meetings:write",
          "client_books:read",
          "books:read",
          "books:write",
          "books:admin",
          "self_assessment:read",
          "self_assessment:write",
          "accounts:read",
          "accounts:write",
          "corporation_tax:read",
          "corporation_tax:write"
        ]
      },
      "ApiCredential": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "kind": {
            "allOf": [
              {
                "$ref": "#/components/schemas/CredentialKind"
              }
            ]
          },
          "name": {
            "type": "string"
          },
          "userId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid",
            "description": "Owner of a personal token."
          },
          "clientId": {
            "type": [
              "string",
              "null"
            ],
            "example": "twc_0123456789abcdef01234567",
            "description": "Public id of an API client."
          },
          "prefix": {
            "type": "string",
            "example": "twp_AbCd",
            "description": "First characters of the secret."
          },
          "scopes": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Scope"
            }
          },
          "role": {
            "description": "Role ceiling of an API client.",
            "oneOf": [
              {
                "$ref": "#/components/schemas/MembershipRole"
              },
              {
                "type": "null"
              }
            ]
          },
          "staffRole": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/StaffRole"
              },
              {
                "type": "null"
              }
            ]
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "lastUsedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "expiresAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "revokedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          }
        },
        "description": "A personal access token or API client. The secret is never returned again.",
        "required": [
          "id",
          "kind",
          "name",
          "userId",
          "clientId",
          "prefix",
          "scopes",
          "role",
          "staffRole",
          "createdAt",
          "lastUsedAt",
          "expiresAt",
          "revokedAt"
        ]
      },
      "CreatePersonalTokenRequest": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 100
          },
          "scopes": {
            "type": "array",
            "minItems": 1,
            "description": "At most what your role allows.",
            "items": {
              "$ref": "#/components/schemas/Scope"
            }
          },
          "expiresInDays": {
            "type": "integer",
            "minimum": 1,
            "maximum": 366,
            "default": 90
          }
        },
        "required": [
          "name",
          "scopes"
        ]
      },
      "CreatedCredential": {
        "type": "object",
        "properties": {
          "credential": {
            "$ref": "#/components/schemas/ApiCredential"
          },
          "secret": {
            "type": "string",
            "description": "The secret. Shown once: store it now."
          }
        },
        "required": [
          "credential",
          "secret"
        ]
      },
      "CreateApiClientRequest": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 100
          },
          "scopes": {
            "type": "array",
            "minItems": 1,
            "items": {
              "$ref": "#/components/schemas/Scope"
            }
          },
          "staffRole": {
            "description": "Role ceiling for the client; never above your own.",
            "allOf": [
              {
                "$ref": "#/components/schemas/StaffRole"
              }
            ]
          }
        },
        "required": [
          "name",
          "scopes",
          "staffRole"
        ]
      },
      "AuditVia": {
        "type": "string",
        "enum": [
          "web",
          "api",
          "mcp"
        ]
      },
      "PrincipalKind": {
        "type": "string",
        "enum": [
          "session",
          "oauth",
          "personal_token",
          "client"
        ]
      },
      "AuditEntry": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "occurredAt": {
            "type": "string",
            "format": "date-time"
          },
          "actorUserId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "principalKind": {
            "allOf": [
              {
                "$ref": "#/components/schemas/PrincipalKind"
              }
            ]
          },
          "credentialId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "clientId": {
            "type": [
              "string",
              "null"
            ]
          },
          "via": {
            "allOf": [
              {
                "$ref": "#/components/schemas/AuditVia"
              }
            ]
          },
          "viaLabel": {
            "type": "string",
            "example": "via MCP (Claude)"
          },
          "method": {
            "type": "string",
            "example": "GET"
          },
          "path": {
            "type": "string",
            "example": "/api/v1/work"
          },
          "status": {
            "type": "integer"
          },
          "tool": {
            "type": [
              "string",
              "null"
            ],
            "example": "list_my_work"
          },
          "action": {
            "type": [
              "string",
              "null"
            ],
            "example": "evidence.download",
            "description": "A sensitive action recorded in the same transaction as the action itself."
          },
          "target": {
            "type": [
              "string",
              "null"
            ],
            "description": "Whose work it was: the client’s name, where the entry can say."
          },
          "summary": {
            "type": "string",
            "example": "Started accounts, Harrow & Finch Ltd",
            "description": "What happened, in words."
          }
        },
        "required": [
          "id",
          "occurredAt",
          "actorUserId",
          "principalKind",
          "credentialId",
          "clientId",
          "via",
          "viaLabel",
          "method",
          "path",
          "status",
          "tool"
        ]
      },
      "AuditPage": {
        "type": "object",
        "properties": {
          "rows": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AuditEntry"
            }
          },
          "nextCursor": {
            "type": [
              "string",
              "null"
            ],
            "description": "Opaque cursor for the next page (pass as `cursor`); null on the last page."
          },
          "pageSize": {
            "type": "integer",
            "minimum": 1,
            "maximum": 100,
            "description": "The page size that was used."
          }
        },
        "required": [
          "rows",
          "nextCursor",
          "pageSize"
        ]
      },
      "GrantType": {
        "type": "string",
        "enum": [
          "client_credentials"
        ]
      },
      "ClientCredentialsTokenRequest": {
        "type": "object",
        "properties": {
          "grant_type": {
            "allOf": [
              {
                "$ref": "#/components/schemas/GrantType"
              }
            ]
          },
          "client_id": {
            "type": "string",
            "description": "Or send HTTP Basic authentication."
          },
          "client_secret": {
            "type": "string"
          },
          "scope": {
            "type": "string",
            "description": "Space-separated subset of the client’s scopes (default: all of them)."
          }
        },
        "required": [
          "grant_type"
        ]
      },
      "TokenType": {
        "type": "string",
        "enum": [
          "Bearer"
        ]
      },
      "TokenResponse": {
        "type": "object",
        "properties": {
          "access_token": {
            "type": "string",
            "example": "twat_…"
          },
          "token_type": {
            "allOf": [
              {
                "$ref": "#/components/schemas/TokenType"
              }
            ]
          },
          "expires_in": {
            "type": "integer",
            "example": 3600
          },
          "scope": {
            "type": "string",
            "example": "work:read clients:read"
          }
        },
        "required": [
          "access_token",
          "token_type",
          "expires_in",
          "scope"
        ]
      },
      "OAuthErrorCode": {
        "type": "string",
        "enum": [
          "invalid_request",
          "invalid_client",
          "invalid_grant",
          "unauthorized_client",
          "unsupported_grant_type",
          "invalid_scope"
        ]
      },
      "OAuthError": {
        "type": "object",
        "properties": {
          "error": {
            "allOf": [
              {
                "$ref": "#/components/schemas/OAuthErrorCode"
              }
            ]
          },
          "error_description": {
            "type": "string"
          }
        },
        "description": "RFC 6749 §5.2 error response.",
        "required": [
          "error"
        ]
      },
      "RollForwardOptions": {
        "type": "object",
        "properties": {
          "priorYearFigures": {
            "type": "boolean",
            "description": "Last year’s final TB (draft + posted journals) as this year’s comparatives, kept when this year’s TB is imported."
          },
          "mappings": {
            "type": "boolean",
            "description": "Last year’s account mappings (codes not yet mapped here)."
          },
          "fixedAssets": {
            "type": "boolean",
            "description": "The fixed asset register: closing cost and depreciation as opening balances, disposed assets left out."
          },
          "taxBroughtForward": {
            "type": "boolean",
            "description": "Main and special rate pool WDVs and trading losses carried forward."
          },
          "notes": {
            "type": "boolean",
            "description": "Last year’s variance notes, as hints on the lead schedules (never as this year’s explanations)."
          }
        },
        "description": "What to bring forward from the prior year. Each defaults to true."
      },
      "CreateEngagement": {
        "type": "object",
        "properties": {
          "clientId": {
            "type": "string",
            "format": "uuid"
          },
          "entityType": {
            "allOf": [
              {
                "$ref": "#/components/schemas/EntityType"
              }
            ]
          },
          "periodStart": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "periodEnd": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "isFirstPeriod": {
            "type": "boolean",
            "description": "First period after incorporation (21-month Companies House deadline)."
          },
          "workflowTemplateId": {
            "type": "string",
            "description": "Workflow template id (a preset id until firm templates exist). Default by entity type."
          },
          "preparerId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid",
            "description": "Leave out to make the caller the preparer (when they are staff); null for nobody yet."
          },
          "reviewerId": {
            "type": "string",
            "format": "uuid"
          },
          "managerId": {
            "type": "string",
            "format": "uuid"
          },
          "partnerId": {
            "type": "string",
            "format": "uuid"
          },
          "risk": {
            "allOf": [
              {
                "$ref": "#/components/schemas/RiskLevel"
              }
            ]
          },
          "bringForward": {
            "description": "What to bring forward from the client’s previous engagement when it starts. Each part defaults to true. Set every part false to leave it as a deliberate step in the new file (POST /engagements/{id}/roll-forward).",
            "allOf": [
              {
                "$ref": "#/components/schemas/RollForwardOptions"
              }
            ]
          }
        },
        "description": "Start an engagement for a client. The entity type defaults to the client’s.",
        "required": [
          "clientId",
          "periodStart",
          "periodEnd"
        ]
      },
      "EngagementTeam": {
        "type": "object",
        "properties": {
          "preparerId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "reviewerId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "managerId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "partnerId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          }
        },
        "required": [
          "preparerId",
          "reviewerId",
          "managerId",
          "partnerId"
        ]
      },
      "Thresholds": {
        "type": "object",
        "properties": {
          "absolutePence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "percent": {
            "type": "integer",
            "minimum": 0
          }
        },
        "description": "Movements at or above both thresholds need an explanation.",
        "required": [
          "absolutePence",
          "percent"
        ]
      },
      "WorkflowStatus": {
        "type": "string",
        "enum": [
          "in_progress",
          "submitted",
          "returned",
          "reopened",
          "approved"
        ]
      },
      "WorkflowStage": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "state": {
            "allOf": [
              {
                "$ref": "#/components/schemas/TimelineStepState"
              }
            ]
          },
          "signedBy": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "signedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "assigneeId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid",
            "description": "Who the engagement team assigns to this stage (preparer, reviewer, manager or partner), or null when nobody is."
          },
          "sentBackBy": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid",
            "description": "While the workflow is returned: who sent it back from this stage."
          },
          "sentBackAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "While the workflow is returned: when it was sent back from this stage."
          }
        },
        "required": [
          "id",
          "name",
          "state",
          "signedBy",
          "signedAt",
          "assigneeId",
          "sentBackBy",
          "sentBackAt"
        ]
      },
      "GuardResult": {
        "type": "object",
        "properties": {
          "allowed": {
            "type": "boolean"
          },
          "reasons": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "codes": {
            "description": "Machine-readable reason codes from @tolvi/workflow.",
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        },
        "description": "Whether the caller can take an action now, and every reason not.",
        "required": [
          "allowed",
          "reasons",
          "codes"
        ]
      },
      "EngagementActions": {
        "type": "object",
        "properties": {
          "submit": {
            "$ref": "#/components/schemas/GuardResult"
          },
          "approve": {
            "$ref": "#/components/schemas/GuardResult"
          },
          "return": {
            "$ref": "#/components/schemas/GuardResult"
          },
          "reopen": {
            "$ref": "#/components/schemas/GuardResult"
          }
        },
        "description": "The engagement-level actions, checked for the caller.",
        "required": [
          "submit",
          "approve",
          "return",
          "reopen"
        ]
      },
      "EngagementWorkflow": {
        "type": "object",
        "properties": {
          "templateId": {
            "type": "string"
          },
          "templateName": {
            "type": "string"
          },
          "status": {
            "allOf": [
              {
                "$ref": "#/components/schemas/EngagementStatus"
              }
            ]
          },
          "workflowStatus": {
            "allOf": [
              {
                "$ref": "#/components/schemas/WorkflowStatus"
              }
            ]
          },
          "currentStageId": {
            "type": "string"
          },
          "currentStageName": {
            "type": "string"
          },
          "currentStageIndex": {
            "type": "integer",
            "minimum": 0
          },
          "stages": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/WorkflowStage"
            }
          },
          "round": {
            "type": "integer",
            "minimum": 1,
            "description": "Amendment round (each return or reopen starts a new one)."
          },
          "returnCount": {
            "type": "integer",
            "minimum": 0
          },
          "reopenCount": {
            "type": "integer",
            "minimum": 0
          },
          "changedAfterApproval": {
            "type": "boolean"
          },
          "returnTargets": {
            "description": "Stages a return can go back to.",
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "actions": {
            "$ref": "#/components/schemas/EngagementActions"
          }
        },
        "required": [
          "templateId",
          "templateName",
          "status",
          "workflowStatus",
          "currentStageId",
          "currentStageName",
          "currentStageIndex",
          "stages",
          "round",
          "returnCount",
          "reopenCount",
          "changedAfterApproval",
          "returnTargets",
          "actions"
        ]
      },
      "TbSourceKind": {
        "type": "string",
        "enum": [
          "csv",
          "excel",
          "api",
          "manual"
        ]
      },
      "TbVersion": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "version": {
            "type": "integer",
            "minimum": 1
          },
          "sourceKind": {
            "allOf": [
              {
                "$ref": "#/components/schemas/TbSourceKind"
              }
            ]
          },
          "sourceLabel": {
            "type": [
              "string",
              "null"
            ]
          },
          "provider": {
            "type": [
              "string",
              "null"
            ]
          },
          "asAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31"
          },
          "booksThroughSeq": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Pulled from Tolvi Books: the ledger point it was read at (the last entry included), so the same trial balance can be recomputed and later entries found exactly. Null for any other source."
          },
          "hash": {
            "type": "string",
            "description": "Content hash (sha256): the same balances give the same hash."
          },
          "accountCount": {
            "type": "integer",
            "minimum": 0
          },
          "cyTotalPence": {
            "type": "integer",
            "description": "Net of current year balances (nil when balanced)."
          },
          "pyTotalPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "balanced": {
            "type": "boolean"
          },
          "removedJournalRefs": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "createdBy": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "version",
          "sourceKind",
          "sourceLabel",
          "provider",
          "asAt",
          "booksThroughSeq",
          "hash",
          "accountCount",
          "cyTotalPence",
          "pyTotalPence",
          "balanced",
          "removedJournalRefs",
          "createdBy",
          "createdAt"
        ]
      },
      "SectionKind": {
        "type": "string",
        "enum": [
          "plan",
          "tb",
          "lead",
          "jnl",
          "fs"
        ]
      },
      "SectionStatus": {
        "type": "string",
        "enum": [
          "todo",
          "progress",
          "prepared",
          "reviewed",
          "changed"
        ]
      },
      "SignOffRole": {
        "type": "string",
        "enum": [
          "preparer",
          "reviewer",
          "manager",
          "partner"
        ],
        "description": "Who signs at this stage, for labels such as \"Sign as reviewer\"."
      },
      "SignOff": {
        "type": "object",
        "properties": {
          "stageId": {
            "type": "string"
          },
          "stageName": {
            "type": "string"
          },
          "signAs": {
            "description": "Who signs at this stage, for labels such as \"Sign as reviewer\".",
            "allOf": [
              {
                "$ref": "#/components/schemas/SignOffRole"
              }
            ]
          },
          "userId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "current": {
            "type": "boolean",
            "description": "Signed against the content as it is now."
          }
        },
        "required": [
          "stageId",
          "stageName",
          "signAs",
          "userId",
          "at",
          "current"
        ]
      },
      "SectionSummary": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string",
            "example": "C"
          },
          "name": {
            "type": "string"
          },
          "kind": {
            "allOf": [
              {
                "$ref": "#/components/schemas/SectionKind"
              }
            ]
          },
          "status": {
            "allOf": [
              {
                "$ref": "#/components/schemas/SectionStatus"
              }
            ]
          },
          "issueCount": {
            "type": "integer",
            "minimum": 0
          },
          "openReviewPoints": {
            "type": "integer",
            "minimum": 0
          },
          "signOffs": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SignOff"
            }
          },
          "currentStageId": {
            "type": [
              "string",
              "null"
            ],
            "description": "Stage the section is at."
          }
        },
        "required": [
          "code",
          "name",
          "kind",
          "status",
          "issueCount",
          "openReviewPoints",
          "signOffs",
          "currentStageId"
        ]
      },
      "NextStepAction": {
        "type": "string",
        "enum": [
          "import",
          "map",
          "journal",
          "explain",
          "reconcile",
          "post_tax",
          "post_deferred_tax",
          "open_tax",
          "fixed_assets",
          "post_fixed_assets",
          "checklist",
          "sign",
          "resign",
          "answer_review_point",
          "check_review_point",
          "raise_review_point",
          "open_section",
          "submit",
          "approve",
          "reopen",
          "wait",
          "none",
          "generate_file",
          "start_next_year"
        ]
      },
      "NextStep": {
        "type": "object",
        "properties": {
          "message": {
            "type": "string"
          },
          "action": {
            "allOf": [
              {
                "$ref": "#/components/schemas/NextStepAction"
              }
            ]
          },
          "label": {
            "type": [
              "string",
              "null"
            ],
            "description": "Button label, e.g. \"Post tax journal\"."
          },
          "target": {
            "type": [
              "string",
              "null"
            ],
            "description": "Section code, journal id, account code or review point id the action is about."
          },
          "done": {
            "type": "boolean",
            "description": "Nothing left for anyone to do here."
          },
          "more": {
            "type": "integer",
            "minimum": 0,
            "description": "Further outstanding items after this one."
          }
        },
        "description": "The first outstanding item and the one action that deals with it.",
        "required": [
          "message",
          "action",
          "label",
          "target",
          "done",
          "more"
        ]
      },
      "EngagementOverview": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "clientId": {
            "type": "string",
            "format": "uuid"
          },
          "clientName": {
            "type": "string"
          },
          "entityType": {
            "allOf": [
              {
                "$ref": "#/components/schemas/EntityType"
              }
            ]
          },
          "periodStart": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "periodEnd": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "isFirstPeriod": {
            "type": "boolean"
          },
          "dueDate": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "risk": {
            "allOf": [
              {
                "$ref": "#/components/schemas/RiskLevel"
              }
            ]
          },
          "team": {
            "$ref": "#/components/schemas/EngagementTeam"
          },
          "thresholds": {
            "$ref": "#/components/schemas/Thresholds"
          },
          "workflow": {
            "$ref": "#/components/schemas/EngagementWorkflow"
          },
          "trialBalance": {
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/TbVersion"
              }
            ]
          },
          "sections": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SectionSummary"
            }
          },
          "openReviewPoints": {
            "type": "integer",
            "minimum": 0
          },
          "unmappedAccounts": {
            "type": "integer",
            "minimum": 0,
            "description": "Trial balance accounts not mapped to a lead schedule line (nil accounts are not counted). Figures from the final TB are incomplete while this is above 0."
          },
          "journalOnlyAccounts": {
            "type": "integer",
            "minimum": 0,
            "description": "Accounts Tolvi added for journals (journal-only: the tax and disposal accounts). B lists them with the TB’s own accounts, so B shows `trialBalance.accountCount` plus these."
          },
          "finalTbAccounts": {
            "type": "integer",
            "minimum": 0,
            "description": "Every account on the final TB (B): the TB version’s accounts, Tolvi’s journal-only accounts and accounts only in last year’s TB."
          },
          "nextStep": {
            "$ref": "#/components/schemas/NextStep"
          }
        },
        "required": [
          "id",
          "clientId",
          "clientName",
          "entityType",
          "periodStart",
          "periodEnd",
          "isFirstPeriod",
          "dueDate",
          "risk",
          "team",
          "thresholds",
          "workflow",
          "trialBalance",
          "sections",
          "openReviewPoints",
          "unmappedAccounts",
          "nextStep"
        ]
      },
      "CancelResult": {
        "type": "object",
        "properties": {
          "cancelled": {
            "type": "boolean"
          },
          "credited": {
            "type": "boolean",
            "description": "Cancelled within 14 days with no sign-offs: a billing credit was written."
          }
        },
        "required": [
          "cancelled",
          "credited"
        ]
      },
      "ChecklistOrigin": {
        "type": "string",
        "enum": [
          "builtin",
          "firm",
          "client"
        ]
      },
      "ChecklistStatus": {
        "type": "string",
        "enum": [
          "",
          "done",
          "na"
        ],
        "description": "\"\" is not yet done."
      },
      "EvidenceStatus": {
        "type": "string",
        "enum": [
          "pending_upload",
          "pending_scan",
          "available",
          "rejected"
        ],
        "description": "pending_upload until POST …/evidence/{evidenceId}/confirm checks the stored file; then pending_scan (malware scan) and available. Only available files can be downloaded or read by Tolvi AI. rejected: the file failed the checks or the scan found malware (see rejectedReason); it can never be downloaded."
      },
      "Evidence": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "sectionCode": {
            "type": [
              "string",
              "null"
            ]
          },
          "checklistItemId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "reviewPointId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "reviewPointMessageId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "fileName": {
            "type": "string"
          },
          "contentType": {
            "type": "string"
          },
          "sizeBytes": {
            "type": "integer",
            "minimum": 0
          },
          "status": {
            "description": "pending_upload until POST …/evidence/{evidenceId}/confirm checks the stored file; then pending_scan (malware scan) and available. Only available files can be downloaded or read by Tolvi AI. rejected: the file failed the checks or the scan found malware (see rejectedReason); it can never be downloaded.",
            "allOf": [
              {
                "$ref": "#/components/schemas/EvidenceStatus"
              }
            ]
          },
          "rejectedReason": {
            "type": [
              "string",
              "null"
            ],
            "description": "Why a rejected file was rejected, e.g. \"malware detected\"; null otherwise."
          },
          "uploadedBy": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "sectionCode",
          "checklistItemId",
          "reviewPointId",
          "reviewPointMessageId",
          "fileName",
          "contentType",
          "sizeBytes",
          "status",
          "rejectedReason",
          "uploadedBy",
          "createdAt"
        ]
      },
      "ChecklistItem": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "position": {
            "type": "integer"
          },
          "text": {
            "type": "string"
          },
          "origin": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ChecklistOrigin"
              }
            ]
          },
          "status": {
            "description": "\"\" is not yet done.",
            "allOf": [
              {
                "$ref": "#/components/schemas/ChecklistStatus"
              }
            ]
          },
          "auto": {
            "type": "boolean",
            "description": "Ticked by Tolvi from the data (a person’s own tick always wins)."
          },
          "note": {
            "type": "string"
          },
          "doneBy": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "doneAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "evidence": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Evidence"
            }
          }
        },
        "required": [
          "id",
          "position",
          "text",
          "origin",
          "status",
          "auto",
          "note",
          "doneBy",
          "doneAt",
          "evidence"
        ]
      },
      "IssueAction": {
        "type": "string",
        "enum": [
          "import",
          "map",
          "journal",
          "explain",
          "reconcile",
          "post_tax",
          "post_deferred_tax",
          "open_tax",
          "fixed_assets",
          "post_fixed_assets",
          "checklist"
        ]
      },
      "Issue": {
        "type": "object",
        "properties": {
          "message": {
            "type": "string"
          },
          "action": {
            "allOf": [
              {
                "$ref": "#/components/schemas/IssueAction"
              }
            ]
          },
          "label": {
            "type": "string"
          },
          "target": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "message",
          "action",
          "label",
          "target"
        ]
      },
      "SectionSignOffPanel": {
        "type": "object",
        "properties": {
          "stages": {
            "description": "Every stage that applies to sections, with its live sign-off.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SignOff"
            }
          },
          "currentStageId": {
            "type": "string"
          },
          "sign": {
            "description": "Can the caller sign at the current stage now?",
            "allOf": [
              {
                "$ref": "#/components/schemas/GuardResult"
              }
            ]
          },
          "ownSignOffStageId": {
            "type": [
              "string",
              "null"
            ],
            "description": "Stage of the caller’s own live sign-off, which they can remove."
          },
          "signStageId": {
            "type": [
              "string",
              "null"
            ],
            "description": "The stage signing now would record the caller’s sign-off at. Usually `currentStageId`; the first stage when the caller re-signs their own out-of-date preparer sign-off (the section is reopened first). Null when there is nothing to sign."
          },
          "unsign": {
            "description": "Can the caller remove their own sign-off now? Refused while the file is signed off at every stage.",
            "allOf": [
              {
                "$ref": "#/components/schemas/GuardResult"
              }
            ]
          },
          "unsignRemoves": {
            "description": "Removing the caller’s own sign-off removes these later sign-offs too (other people’s).",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SignOff"
            }
          },
          "fingerprint": {
            "type": "string",
            "description": "Content fingerprint now."
          }
        },
        "required": [
          "stages",
          "currentStageId",
          "sign",
          "ownSignOffStageId",
          "fingerprint"
        ]
      },
      "ReviewPointCategory": {
        "type": "string",
        "enum": [
          "query",
          "error",
          "presentation",
          "missing_evidence"
        ]
      },
      "ReviewPointStatus": {
        "type": "string",
        "enum": [
          "open",
          "answered",
          "cleared",
          "reopened"
        ]
      },
      "ReviewPointMessageKind": {
        "type": "string",
        "enum": [
          "raise",
          "comment",
          "answer",
          "clear",
          "reopen"
        ]
      },
      "ReviewPointMessage": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "kind": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ReviewPointMessageKind"
              }
            ]
          },
          "authorId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "body": {
            "type": "string"
          },
          "mentions": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "uuid"
            }
          },
          "at": {
            "type": "string",
            "format": "date-time"
          },
          "evidence": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Evidence"
            }
          }
        },
        "required": [
          "id",
          "kind",
          "authorId",
          "body",
          "mentions",
          "at",
          "evidence"
        ]
      },
      "ReviewPoint": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "sectionCode": {
            "type": [
              "string",
              "null"
            ],
            "description": "Null for a point on the engagement as a whole."
          },
          "category": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ReviewPointCategory"
              }
            ]
          },
          "status": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ReviewPointStatus"
              }
            ]
          },
          "raisedAtStageId": {
            "type": "string"
          },
          "raisedInRound": {
            "type": "integer",
            "minimum": 1
          },
          "raisedBy": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "raisedAt": {
            "type": "string",
            "format": "date-time"
          },
          "clearedBy": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "clearedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "sourceMeetingId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid",
            "description": "The meeting whose next step this point came from (Create follow-ups in Tolvi Meetings), if any."
          },
          "messages": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ReviewPointMessage"
            }
          }
        },
        "required": [
          "id",
          "sectionCode",
          "category",
          "status",
          "raisedAtStageId",
          "raisedInRound",
          "raisedBy",
          "raisedAt",
          "clearedBy",
          "clearedAt",
          "messages"
        ]
      },
      "SectionDetail": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string",
            "example": "C"
          },
          "name": {
            "type": "string"
          },
          "kind": {
            "allOf": [
              {
                "$ref": "#/components/schemas/SectionKind"
              }
            ]
          },
          "status": {
            "allOf": [
              {
                "$ref": "#/components/schemas/SectionStatus"
              }
            ]
          },
          "issueCount": {
            "type": "integer",
            "minimum": 0
          },
          "openReviewPoints": {
            "type": "integer",
            "minimum": 0
          },
          "signOffs": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SignOff"
            }
          },
          "currentStageId": {
            "type": [
              "string",
              "null"
            ],
            "description": "Stage the section is at."
          },
          "checklist": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ChecklistItem"
            }
          },
          "issues": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Issue"
            }
          },
          "signOff": {
            "$ref": "#/components/schemas/SectionSignOffPanel"
          },
          "nextStep": {
            "$ref": "#/components/schemas/NextStep"
          },
          "reviewPoints": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ReviewPoint"
            }
          },
          "evidence": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Evidence"
            }
          }
        },
        "required": [
          "code",
          "name",
          "kind",
          "status",
          "issueCount",
          "openReviewPoints",
          "signOffs",
          "currentStageId",
          "checklist",
          "issues",
          "signOff",
          "nextStep",
          "reviewPoints",
          "evidence"
        ]
      },
      "LeadLineId": {
        "type": "string",
        "enum": [
          "C.cost",
          "C.dep",
          "D.stk",
          "E.td",
          "E.pre",
          "F.bank",
          "G.tc",
          "G.acc",
          "H.vat",
          "I.paye",
          "J.dla",
          "J.loanst",
          "J.loan",
          "K.cap",
          "K.res",
          "K.div",
          "L.sales",
          "L.intrec",
          "M.cos",
          "M.adm",
          "M.dis",
          "M.dep",
          "M.int",
          "M.disp",
          "T.chg",
          "T.liab",
          "T.dtc",
          "P.dt",
          "J.cap",
          "J.draw"
        ]
      },
      "Statement": {
        "type": "string",
        "enum": [
          "BS",
          "PL",
          "EQ"
        ]
      },
      "VarianceNote": {
        "type": "object",
        "properties": {
          "body": {
            "type": "string"
          },
          "authorId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          },
          "editable": {
            "type": "boolean",
            "description": "The caller wrote it, so can change it."
          }
        },
        "required": [
          "body",
          "authorId",
          "updatedAt",
          "editable"
        ]
      },
      "Tickmark": {
        "type": "string",
        "enum": [
          "✓",
          "‹",
          "^",
          "✗"
        ]
      },
      "TickmarkEntry": {
        "type": "object",
        "properties": {
          "mark": {
            "allOf": [
              {
                "$ref": "#/components/schemas/Tickmark"
              }
            ]
          },
          "label": {
            "type": "string"
          },
          "authorId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          },
          "editable": {
            "type": "boolean"
          }
        },
        "required": [
          "mark",
          "label",
          "authorId",
          "updatedAt",
          "editable"
        ]
      },
      "LeadAccount": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "pyPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "draftPence": {
            "type": "integer",
            "description": "Per the imported (draft) TB."
          },
          "adjustmentsPence": {
            "type": "integer",
            "description": "Posted journals."
          },
          "draftJournalsPence": {
            "type": "integer",
            "description": "Draft journals, not in the final figure."
          },
          "finalPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "movementPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "movementPct": {
            "type": [
              "number",
              "null"
            ],
            "description": "Movement as a percentage of last year, 1 dp; null when last year was nil."
          },
          "needsExplanation": {
            "type": "boolean"
          },
          "note": {
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/VarianceNote"
              }
            ]
          },
          "lastYearNote": {
            "type": [
              "string",
              "null"
            ],
            "description": "Last year’s explanation, brought forward as a hint: it never counts as this year’s."
          },
          "tickmark": {
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/TickmarkEntry"
              }
            ]
          }
        },
        "required": [
          "code",
          "name",
          "pyPence",
          "draftPence",
          "adjustmentsPence",
          "draftJournalsPence",
          "finalPence",
          "movementPence",
          "movementPct",
          "needsExplanation",
          "note",
          "lastYearNote",
          "tickmark"
        ]
      },
      "LeadTotals": {
        "type": "object",
        "properties": {
          "pyPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "draftPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "adjustmentsPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "finalPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          }
        },
        "required": [
          "pyPence",
          "draftPence",
          "adjustmentsPence",
          "finalPence"
        ]
      },
      "LeadLine": {
        "type": "object",
        "properties": {
          "lineId": {
            "allOf": [
              {
                "$ref": "#/components/schemas/LeadLineId"
              }
            ]
          },
          "label": {
            "type": "string"
          },
          "statement": {
            "allOf": [
              {
                "$ref": "#/components/schemas/Statement"
              }
            ]
          },
          "accounts": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/LeadAccount"
            }
          },
          "totals": {
            "$ref": "#/components/schemas/LeadTotals"
          }
        },
        "required": [
          "lineId",
          "label",
          "statement",
          "accounts",
          "totals"
        ]
      },
      "LeadSchedule": {
        "type": "object",
        "properties": {
          "sectionCode": {
            "type": "string"
          },
          "sectionName": {
            "type": "string"
          },
          "thresholds": {
            "$ref": "#/components/schemas/Thresholds"
          },
          "lines": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/LeadLine"
            }
          },
          "totals": {
            "$ref": "#/components/schemas/LeadTotals"
          }
        },
        "required": [
          "sectionCode",
          "sectionName",
          "thresholds",
          "lines",
          "totals"
        ]
      },
      "ReconciliationKind": {
        "type": "string",
        "enum": [
          "bank",
          "vat",
          "paye",
          "pension",
          "cis",
          "dla",
          "loan"
        ],
        "description": "What the account is reconciled to: bank statement, VAT return, P32, pension schedule, CIS300, DLA or current account schedule, lender statement."
      },
      "RecItem": {
        "type": "object",
        "properties": {
          "description": {
            "type": "string",
            "maxLength": 200
          },
          "amountPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          }
        },
        "required": [
          "description",
          "amountPence"
        ]
      },
      "Reconciliation": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "sectionCode": {
            "type": "string"
          },
          "kind": {
            "description": "What the account is reconciled to: bank statement, VAT return, P32, pension schedule, CIS300, DLA or current account schedule, lender statement.",
            "allOf": [
              {
                "$ref": "#/components/schemas/ReconciliationKind"
              }
            ]
          },
          "title": {
            "type": "string"
          },
          "sourceLabel": {
            "type": "string"
          },
          "sourcePence": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Per the source document, in its own sign (e.g. VAT payable is positive)."
          },
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/RecItem"
            }
          },
          "note": {
            "type": "string"
          },
          "tbPence": {
            "type": "integer",
            "description": "Final TB balance in the source document’s sign."
          },
          "expectedPence": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Integer pence (GBP)."
          },
          "differencePence": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Integer pence (GBP)."
          },
          "agrees": {
            "type": "boolean"
          },
          "ok": {
            "type": "boolean",
            "description": "Agrees, or the difference is explained in the note."
          }
        },
        "required": [
          "code",
          "name",
          "sectionCode",
          "kind",
          "title",
          "sourceLabel",
          "sourcePence",
          "items",
          "note",
          "tbPence",
          "expectedPence",
          "differencePence",
          "agrees",
          "ok"
        ]
      },
      "SectionNextStep": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "status": {
            "allOf": [
              {
                "$ref": "#/components/schemas/SectionStatus"
              }
            ]
          },
          "nextStep": {
            "$ref": "#/components/schemas/NextStep"
          }
        },
        "required": [
          "code",
          "name",
          "status",
          "nextStep"
        ]
      },
      "NextSteps": {
        "type": "object",
        "properties": {
          "engagement": {
            "$ref": "#/components/schemas/NextStep"
          },
          "sections": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SectionNextStep"
            }
          }
        },
        "description": "The engagement’s next step and each section’s, for the caller.",
        "required": [
          "engagement",
          "sections"
        ]
      },
      "SetVarianceNote": {
        "type": "object",
        "properties": {
          "body": {
            "type": "string",
            "minLength": 1,
            "maxLength": 4000
          }
        },
        "required": [
          "body"
        ]
      },
      "SetTickmark": {
        "type": "object",
        "properties": {
          "mark": {
            "allOf": [
              {
                "$ref": "#/components/schemas/Tickmark"
              }
            ]
          }
        },
        "required": [
          "mark"
        ]
      },
      "SetReconciliation": {
        "type": "object",
        "properties": {
          "sourcePence": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Integer pence (GBP)."
          },
          "items": {
            "maxItems": 200,
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/RecItem"
            }
          },
          "note": {
            "type": "string",
            "maxLength": 4000
          }
        },
        "required": [
          "sourcePence",
          "items"
        ]
      },
      "UpdateChecklistItem": {
        "type": "object",
        "properties": {
          "status": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ChecklistStatus"
              }
            ]
          },
          "note": {
            "type": "string",
            "maxLength": 4000
          }
        }
      },
      "CreateEvidence": {
        "type": "object",
        "properties": {
          "sectionCode": {
            "type": "string"
          },
          "checklistItemId": {
            "type": "string",
            "format": "uuid"
          },
          "reviewPointId": {
            "type": "string",
            "format": "uuid"
          },
          "fileName": {
            "type": "string",
            "minLength": 1,
            "maxLength": 200
          },
          "contentType": {
            "type": "string",
            "maxLength": 100,
            "example": "application/pdf"
          },
          "sizeBytes": {
            "type": "integer",
            "minimum": 1,
            "maximum": 104857600
          }
        },
        "description": "Give a section (optionally a checklist step) or a review point. Accepted files: PDF (.pdf); images (.png, .jpg/.jpeg, .heic/.heif, .webp); Excel (.xlsx, .xls); Word (.docx, .doc); .csv; .txt; email (.eml, .msg). The extension decides the type: contentType must agree with it (or be application/octet-stream when unknown), and the upload headers returned carry the type to PUT with. The stored bytes are checked against the type when the upload is confirmed.",
        "required": [
          "fileName",
          "contentType",
          "sizeBytes"
        ]
      },
      "PresignedMethod": {
        "type": "string",
        "enum": [
          "PUT",
          "GET"
        ]
      },
      "PresignedUpload": {
        "type": "object",
        "properties": {
          "url": {
            "type": "string",
            "format": "uri"
          },
          "method": {
            "allOf": [
              {
                "$ref": "#/components/schemas/PresignedMethod"
              }
            ]
          },
          "headers": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            },
            "description": "Headers to send with the request."
          },
          "expiresAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "url",
          "method",
          "headers",
          "expiresAt"
        ]
      },
      "EvidenceUpload": {
        "type": "object",
        "properties": {
          "evidence": {
            "$ref": "#/components/schemas/Evidence"
          },
          "upload": {
            "$ref": "#/components/schemas/PresignedUpload"
          }
        },
        "required": [
          "evidence",
          "upload"
        ]
      },
      "AccountType": {
        "type": "string",
        "enum": [
          "asset",
          "liability",
          "equity",
          "revenue",
          "expense"
        ]
      },
      "TbAccountInput": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string",
            "maxLength": 50
          },
          "name": {
            "type": "string",
            "maxLength": 200
          },
          "cyPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "pyPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "type": {
            "allOf": [
              {
                "$ref": "#/components/schemas/AccountType"
              }
            ]
          }
        },
        "required": [
          "code",
          "name",
          "cyPence"
        ]
      },
      "TbProvider": {
        "type": "string",
        "enum": [
          "xero",
          "quickbooks",
          "sage",
          "freeagent",
          "tolvi_books"
        ]
      },
      "TbImport": {
        "type": "object",
        "properties": {
          "format": {
            "allOf": [
              {
                "$ref": "#/components/schemas/TbImportFormat"
              }
            ]
          },
          "content": {
            "type": "string",
            "maxLength": 2000000
          },
          "sheet": {
            "$ref": "#/components/schemas/TbSheet"
          },
          "accounts": {
            "maxItems": 20000,
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TbAccountInput"
            }
          },
          "asAt": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31",
            "description": "Overrides any date in the file."
          },
          "sourceLabel": {
            "type": "string",
            "maxLength": 200,
            "description": "File name, shown in the version list."
          },
          "provider": {
            "allOf": [
              {
                "$ref": "#/components/schemas/TbProvider"
              }
            ]
          },
          "confirmJournalRemoval": {
            "type": "boolean",
            "description": "Required when the import removes journals (see the preview)."
          },
          "reopenFile": {
            "type": "boolean",
            "description": "Required to import into a file signed off at every stage (the preview’s `importLock` says so): the import reopens the file for re-approval, as `POST …/workflow/reopen`, in the same transaction. Only a reviewer or above (review:write) can reopen; 409 without it, 403 for anyone else."
          },
          "columns": {
            "description": "csv and sheet only: read these columns instead of detecting them. The preview’s `layout` shows what was detected.",
            "allOf": [
              {
                "$ref": "#/components/schemas/TbColumns"
              }
            ]
          }
        },
        "description": "A CSV export (`format: csv`, `content`), one worksheet of a workbook (`format: sheet`, `sheet`) or structured accounts (`format: json`, `accounts`).",
        "required": [
          "format"
        ]
      },
      "JournalStatus": {
        "type": "string",
        "enum": [
          "draft",
          "posted"
        ]
      },
      "JournalRef": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "ref": {
            "type": "string"
          },
          "status": {
            "allOf": [
              {
                "$ref": "#/components/schemas/JournalStatus"
              }
            ]
          }
        },
        "required": [
          "id",
          "ref",
          "status"
        ]
      },
      "TbPreviewAccount": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "cyPence": {
            "type": "integer",
            "description": "Current year balance in integer pence: debits positive, credits negative."
          },
          "pyPence": {
            "type": "integer",
            "description": "Prior year balance in integer pence: debits positive, credits negative."
          },
          "lineId": {
            "description": "The mapping already held for this code, else the one found automatically; null when it needs mapping.",
            "oneOf": [
              {
                "$ref": "#/components/schemas/LeadLineId"
              },
              {
                "type": "null"
              }
            ]
          }
        },
        "description": "One account as read from the file, with the lead schedule line it would be on.",
        "required": [
          "code",
          "name",
          "cyPence",
          "pyPence",
          "lineId"
        ]
      },
      "TbStaleSignOff": {
        "type": "object",
        "properties": {
          "sectionCode": {
            "type": "string"
          },
          "sectionName": {
            "type": "string"
          },
          "stages": {
            "description": "The stages whose sign-off would go out of date, e.g. \"Preparer\", \"Reviewer\".",
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        },
        "description": "A section whose current sign-offs would go out of date if this trial balance were imported.",
        "required": [
          "sectionCode",
          "sectionName",
          "stages"
        ]
      },
      "TbImportLockCode": {
        "type": "string",
        "enum": [
          "file_signed_off",
          "reopen_not_permitted"
        ]
      },
      "TbImportLock": {
        "type": "object",
        "properties": {
          "code": {
            "allOf": [
              {
                "$ref": "#/components/schemas/TbImportLockCode"
              }
            ]
          },
          "reason": {
            "type": "string",
            "description": "In plain words, for the import screen."
          },
          "canReopen": {
            "type": "boolean",
            "description": "The caller can import anyway by reopening the file (send `reopenFile: true`). False for a preparer: a reviewer or above reopens it first."
          }
        },
        "description": "Why a new trial balance cannot simply be imported now: the file is signed off at every stage.",
        "required": [
          "code",
          "reason",
          "canReopen"
        ]
      },
      "TbImportPreview": {
        "type": "object",
        "properties": {
          "accountCount": {
            "type": "integer"
          },
          "addedCodes": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "removedCodes": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "changedCount": {
            "type": "integer",
            "description": "Accounts whose balances differ from the current version."
          },
          "cyTotalPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "balanced": {
            "type": "boolean"
          },
          "hash": {
            "type": "string"
          },
          "sameAsCurrent": {
            "type": "boolean",
            "description": "Identical to the current version (an import would be refused)."
          },
          "journalsToRemove": {
            "description": "Journals whose accounts are not in the new TB: confirm before they are removed.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/JournalRef"
            }
          },
          "unmappedCount": {
            "type": "integer",
            "description": "Accounts nothing could map."
          },
          "debitTotalPence": {
            "type": "integer",
            "description": "Current year debit balances added up, in integer pence."
          },
          "creditTotalPence": {
            "type": "integer",
            "description": "Current year credit balances added up, in integer pence (negative)."
          },
          "accounts": {
            "description": "The accounts as read, in file order.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TbPreviewAccount"
            }
          },
          "warnings": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TbWarning"
            }
          },
          "layout": {
            "description": "The header row and columns read (detected, or as given in `columns`). Null for structured accounts.",
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/TbColumns"
              }
            ]
          },
          "staleSignOffs": {
            "description": "Sections whose current sign-offs this import would put out of date.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TbStaleSignOff"
            }
          },
          "importLock": {
            "description": "Set when the file is signed off at every stage: the import is refused unless it reopens the file.",
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/TbImportLock"
              }
            ]
          }
        },
        "description": "What an import would do. Nothing is stored.",
        "required": [
          "accountCount",
          "addedCodes",
          "removedCodes",
          "changedCount",
          "cyTotalPence",
          "balanced",
          "hash",
          "sameAsCurrent",
          "journalsToRemove",
          "unmappedCount",
          "debitTotalPence",
          "creditTotalPence",
          "accounts",
          "warnings",
          "layout",
          "staleSignOffs"
        ]
      },
      "TbImportResult": {
        "type": "object",
        "properties": {
          "version": {
            "$ref": "#/components/schemas/TbVersion"
          },
          "removedJournalRefs": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "warnings": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TbWarning"
            }
          },
          "unmappedCount": {
            "type": "integer"
          }
        },
        "required": [
          "version",
          "removedJournalRefs",
          "warnings",
          "unmappedCount"
        ]
      },
      "FinalTbAccount": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "journalOnly": {
            "type": "boolean",
            "description": "Added in Tolvi for journals (journal-only): in no TB version, so draft and prior year are nil and the final balance is journals only."
          },
          "chartOnly": {
            "type": "boolean",
            "description": "An account on the client’s chart of accounts with no balance in this TB, used here by C or a journal: shown under the client’s own code, with nil draft and prior year, so it matches their books once they post it."
          },
          "lineId": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/LeadLineId"
              },
              {
                "type": "null"
              }
            ]
          },
          "lineLabel": {
            "type": [
              "string",
              "null"
            ]
          },
          "sectionCode": {
            "type": [
              "string",
              "null"
            ]
          },
          "pyPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "draftPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "adjustmentsPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "draftJournalsPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "finalPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "needsExplanation": {
            "type": "boolean",
            "description": "Final against prior year moved by at least both of the year-end file’s review thresholds: the same test as a lead schedule line. T’s accounts are explained by the tax computation, so never."
          }
        },
        "required": [
          "code",
          "name",
          "lineId",
          "lineLabel",
          "sectionCode",
          "pyPence",
          "draftPence",
          "adjustmentsPence",
          "draftJournalsPence",
          "finalPence",
          "needsExplanation"
        ]
      },
      "FinalTrialBalance": {
        "type": "object",
        "properties": {
          "version": {
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/TbVersion"
              }
            ]
          },
          "accounts": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/FinalTbAccount"
            }
          },
          "draftTotalPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "finalTotalPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "pyTotalPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "balanced": {
            "type": "boolean"
          }
        },
        "description": "Draft TB + posted journals, derived on every request (never stored).",
        "required": [
          "version",
          "accounts",
          "draftTotalPence",
          "finalTotalPence",
          "pyTotalPence",
          "balanced"
        ]
      },
      "MappingSource": {
        "type": "string",
        "enum": [
          "client",
          "firm",
          "books",
          "builtin",
          "manual",
          "chart"
        ],
        "description": "chart: an account on the client’s chart of accounts with no balance in this TB, put on the line its use in C implies or the mapping order suggested. books: the account’s lead schedule line in the client’s Tolvi Books."
      },
      "AccountMapping": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "lineId": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/LeadLineId"
              },
              {
                "type": "null"
              }
            ]
          },
          "source": {
            "description": "chart: an account on the client’s chart of accounts with no balance in this TB, put on the line its use in C implies or the mapping order suggested. books: the account’s lead schedule line in the client’s Tolvi Books.",
            "oneOf": [
              {
                "$ref": "#/components/schemas/MappingSource"
              },
              {
                "type": "null"
              }
            ]
          },
          "explanation": {
            "type": "string"
          },
          "allowed": {
            "type": "boolean",
            "description": "The line can be used for this entity type."
          }
        },
        "required": [
          "code",
          "name",
          "lineId",
          "source",
          "explanation",
          "allowed"
        ]
      },
      "MappingLine": {
        "type": "object",
        "properties": {
          "id": {
            "allOf": [
              {
                "$ref": "#/components/schemas/LeadLineId"
              }
            ]
          },
          "label": {
            "type": "string"
          },
          "sectionCode": {
            "type": "string"
          },
          "allowed": {
            "type": "boolean"
          }
        },
        "required": [
          "id",
          "label",
          "sectionCode",
          "allowed"
        ]
      },
      "Mappings": {
        "type": "object",
        "properties": {
          "accounts": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AccountMapping"
            }
          },
          "lines": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/MappingLine"
            }
          },
          "unmappedCount": {
            "type": "integer"
          },
          "lockedReason": {
            "type": [
              "string",
              "null"
            ],
            "description": "Why the caller cannot change mappings now (B reviewed): ask the reviewer to reopen it."
          },
          "importLock": {
            "description": "Set when a new trial balance cannot simply be imported: the file is signed off at every stage. B’s import panel says so before anyone starts.",
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/TbImportLock"
              }
            ]
          }
        },
        "required": [
          "accounts",
          "lines",
          "unmappedCount"
        ]
      },
      "MappingChange": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string"
          },
          "lineId": {
            "description": "Null to unmap.",
            "oneOf": [
              {
                "$ref": "#/components/schemas/LeadLineId"
              },
              {
                "type": "null"
              }
            ]
          }
        },
        "required": [
          "code",
          "lineId"
        ]
      },
      "SetMappings": {
        "type": "object",
        "properties": {
          "mappings": {
            "minItems": 1,
            "maxItems": 5000,
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/MappingChange"
            }
          },
          "remember": {
            "type": "boolean",
            "description": "Remember for this client’s future engagements (client memory). Default true."
          }
        },
        "required": [
          "mappings"
        ]
      },
      "JournalType": {
        "type": "string",
        "enum": [
          "Adjusting",
          "Reclassification",
          "Correction"
        ]
      },
      "JournalAutoKind": {
        "type": "string",
        "enum": [
          "ct",
          "deferred",
          "fixed_assets"
        ],
        "description": "Posted by Tolvi from the tax computation (ct, deferred) or the fixed asset register (fixed_assets)."
      },
      "JournalLine": {
        "type": "object",
        "properties": {
          "accountCode": {
            "type": "string"
          },
          "accountName": {
            "type": [
              "string",
              "null"
            ]
          },
          "debitPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "creditPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          }
        },
        "required": [
          "accountCode",
          "accountName",
          "debitPence",
          "creditPence"
        ]
      },
      "Journal": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "ref": {
            "type": "string",
            "example": "JNL-03"
          },
          "date": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "type": {
            "allOf": [
              {
                "$ref": "#/components/schemas/JournalType"
              }
            ]
          },
          "status": {
            "allOf": [
              {
                "$ref": "#/components/schemas/JournalStatus"
              }
            ]
          },
          "narrative": {
            "type": "string"
          },
          "autoKind": {
            "description": "Posted by Tolvi from the tax computation (ct, deferred) or the fixed asset register (fixed_assets).",
            "oneOf": [
              {
                "$ref": "#/components/schemas/JournalAutoKind"
              },
              {
                "type": "null"
              }
            ]
          },
          "lines": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/JournalLine"
            }
          },
          "sectionCodes": {
            "description": "Lead sections the journal touches.",
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "lockedBySections": {
            "description": "Reviewed sections that lock it: only a reviewer or above can unpost or delete it.",
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "createdBy": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "postedBy": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "postedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "ref",
          "date",
          "type",
          "status",
          "narrative",
          "autoKind",
          "lines",
          "sectionCodes",
          "lockedBySections",
          "createdBy",
          "createdAt",
          "postedBy",
          "postedAt"
        ]
      },
      "JournalLineInput": {
        "type": "object",
        "properties": {
          "accountCode": {
            "type": "string"
          },
          "debitPence": {
            "type": "integer",
            "description": "Integer pence (GBP).",
            "minimum": 0
          },
          "creditPence": {
            "type": "integer",
            "description": "Integer pence (GBP).",
            "minimum": 0
          }
        },
        "required": [
          "accountCode",
          "debitPence",
          "creditPence"
        ]
      },
      "CreateJournal": {
        "type": "object",
        "properties": {
          "date": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31",
            "description": "Default: the period end."
          },
          "type": {
            "allOf": [
              {
                "$ref": "#/components/schemas/JournalType"
              }
            ]
          },
          "narrative": {
            "type": "string",
            "minLength": 1,
            "maxLength": 1000
          },
          "status": {
            "description": "Default draft.",
            "allOf": [
              {
                "$ref": "#/components/schemas/JournalStatus"
              }
            ]
          },
          "lines": {
            "minItems": 2,
            "maxItems": 200,
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/JournalLineInput"
            }
          }
        },
        "required": [
          "type",
          "narrative",
          "lines"
        ]
      },
      "JournalImpactAction": {
        "type": "string",
        "enum": [
          "post",
          "unpost",
          "delete"
        ]
      },
      "JournalImpactRequest": {
        "type": "object",
        "properties": {
          "journalId": {
            "type": "string",
            "format": "uuid",
            "description": "A saved journal. Give action too."
          },
          "action": {
            "allOf": [
              {
                "$ref": "#/components/schemas/JournalImpactAction"
              }
            ]
          },
          "lines": {
            "minItems": 1,
            "maxItems": 200,
            "description": "A new journal’s lines (instead of journalId).",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/JournalLineInput"
            }
          },
          "status": {
            "description": "For new lines: posted (default) or draft.",
            "allOf": [
              {
                "$ref": "#/components/schemas/JournalStatus"
              }
            ]
          },
          "date": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31",
            "description": "For new lines. Default: the period end."
          }
        },
        "description": "Either a journal not yet saved (lines, with status) or a saved one and what would be done to it."
      },
      "StaleSignOff": {
        "type": "object",
        "properties": {
          "stageId": {
            "type": "string"
          },
          "stageName": {
            "type": "string"
          },
          "userId": {
            "type": "string",
            "format": "uuid"
          }
        },
        "required": [
          "stageId",
          "stageName",
          "userId"
        ]
      },
      "SectionImpact": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "staleSignOffs": {
            "description": "Live sign-offs on the section that would go out of date.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/StaleSignOff"
            }
          }
        },
        "required": [
          "code",
          "name",
          "staleSignOffs"
        ]
      },
      "FigureKey": {
        "type": "string",
        "enum": [
          "profit_before_tax",
          "corporation_tax",
          "tax_charge",
          "net_profit"
        ]
      },
      "FigureChange": {
        "type": "object",
        "properties": {
          "key": {
            "allOf": [
              {
                "$ref": "#/components/schemas/FigureKey"
              }
            ]
          },
          "label": {
            "type": "string"
          },
          "beforePence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "afterPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          }
        },
        "required": [
          "key",
          "label",
          "beforePence",
          "afterPence"
        ]
      },
      "JournalImpact": {
        "type": "object",
        "properties": {
          "sections": {
            "description": "Sections whose content would change, in file order.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SectionImpact"
            }
          },
          "figures": {
            "description": "Headline figures that would move.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/FigureChange"
            }
          }
        },
        "description": "What a journal change would do, worked out without saving anything.",
        "required": [
          "sections",
          "figures"
        ]
      },
      "JournalAccount": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "lineId": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/LeadLineId"
              },
              {
                "type": "null"
              }
            ]
          },
          "lineLabel": {
            "type": [
              "string",
              "null"
            ]
          },
          "journalRefs": {
            "description": "Journals that post to it (it cannot be removed while any do).",
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        },
        "description": "An account Tolvi added for journals (journal-only): in no TB version, so its final balance comes from journals only.",
        "required": [
          "code",
          "name",
          "lineId",
          "lineLabel",
          "journalRefs"
        ]
      },
      "JournalAccountPurpose": {
        "type": "string",
        "enum": [
          "ct_charge",
          "ct_creditor",
          "dt_charge",
          "dt_provision",
          "disposal",
          "disposal_proceeds"
        ]
      },
      "JournalAccountSuggestion": {
        "type": "object",
        "properties": {
          "purpose": {
            "allOf": [
              {
                "$ref": "#/components/schemas/JournalAccountPurpose"
              }
            ]
          },
          "code": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "lineId": {
            "allOf": [
              {
                "$ref": "#/components/schemas/LeadLineId"
              }
            ]
          },
          "needed": {
            "type": "boolean",
            "description": "Nothing on the TB or among Tolvi’s accounts serves this purpose yet."
          }
        },
        "description": "A standard journal-only account Tolvi offers, with a code free on this engagement.",
        "required": [
          "purpose",
          "code",
          "name",
          "lineId",
          "needed"
        ]
      },
      "JournalAccounts": {
        "type": "object",
        "properties": {
          "accounts": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/JournalAccount"
            }
          },
          "suggestions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/JournalAccountSuggestion"
            }
          }
        },
        "required": [
          "accounts",
          "suggestions"
        ]
      },
      "NewJournalAccount": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string",
            "maxLength": 50,
            "description": "Letters, digits, - . or /; not already an account on the engagement."
          },
          "name": {
            "type": "string",
            "maxLength": 200
          },
          "lineId": {
            "allOf": [
              {
                "$ref": "#/components/schemas/LeadLineId"
              }
            ]
          }
        },
        "required": [
          "code",
          "name",
          "lineId"
        ]
      },
      "CreateJournalAccounts": {
        "type": "object",
        "properties": {
          "accounts": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/NewJournalAccount"
            }
          }
        },
        "required": [
          "accounts"
        ]
      },
      "EngagementAccount": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "lineId": {
            "description": "The account’s lead schedule line: B’s mapping, else what the chart suggests. Null when unmapped.",
            "oneOf": [
              {
                "$ref": "#/components/schemas/LeadLineId"
              },
              {
                "type": "null"
              }
            ]
          },
          "lineLabel": {
            "type": [
              "string",
              "null"
            ]
          },
          "sectionCode": {
            "type": [
              "string",
              "null"
            ],
            "description": "The lead schedule (section) of the line."
          },
          "inTb": {
            "type": "boolean",
            "description": "In the imported trial balance. False for a chart account with no balance in this TB, and for journal-only accounts."
          },
          "journalOnly": {
            "type": "boolean"
          },
          "inChart": {
            "type": "boolean",
            "description": "On the client’s chart of accounts."
          },
          "active": {
            "type": "boolean",
            "description": "False for an account archived or inactive in the client’s books."
          },
          "finalPence": {
            "type": "integer",
            "description": "Final TB balance, integer pence, debit positive (nil for an account with no balance yet)."
          }
        },
        "description": "An account a picker can offer: on the TB, one of Tolvi’s journal-only accounts, or on the client’s chart of accounts.",
        "required": [
          "code",
          "name",
          "lineId",
          "lineLabel",
          "sectionCode",
          "inTb",
          "journalOnly",
          "inChart",
          "active",
          "finalPence"
        ]
      },
      "EngagementAccounts": {
        "type": "object",
        "properties": {
          "source": {
            "type": [
              "string",
              "null"
            ],
            "description": "Where the client’s chart of accounts came from: xero, quickbooks, sage, freeagent or csv; null when there is none (the TB’s accounts only)."
          },
          "sourceLabel": {
            "type": [
              "string",
              "null"
            ],
            "example": "Xero"
          },
          "syncedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "When the chart was last read or imported."
          },
          "connectedTo": {
            "type": [
              "string",
              "null"
            ],
            "example": "Xero",
            "description": "The software the client’s books are connected to, so the chart can be refreshed; null when not connected."
          },
          "accounts": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/EngagementAccount"
            }
          }
        },
        "required": [
          "source",
          "sourceLabel",
          "syncedAt",
          "connectedTo",
          "accounts"
        ]
      },
      "TaxAdjustmentInput": {
        "type": "object",
        "properties": {
          "description": {
            "type": "string",
            "maxLength": 200
          },
          "amountPence": {
            "type": "integer",
            "description": "Positive adds back, negative deducts."
          }
        },
        "required": [
          "description",
          "amountPence"
        ]
      },
      "LossesBroughtForward": {
        "type": "object",
        "properties": {
          "pre2017Pence": {
            "type": "integer",
            "description": "Integer pence (GBP).",
            "minimum": 0
          },
          "post2017Pence": {
            "type": "integer",
            "description": "Integer pence (GBP).",
            "minimum": 0
          }
        },
        "description": "Trading losses brought forward, by regime (CTA 2010 s45 before April 2017, s45A after).",
        "required": [
          "pre2017Pence",
          "post2017Pence"
        ]
      },
      "TaxInputs": {
        "type": "object",
        "properties": {
          "associatedCompanies": {
            "type": "integer",
            "minimum": 0,
            "maximum": 1000
          },
          "aiaPence": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Deprecated: capital allowances come from the fixed asset register (section C, /fixed-assets). Echoes the register’s figure. AIA claimed.",
            "deprecated": true
          },
          "mainPoolBfPence": {
            "type": "integer",
            "description": "Deprecated: capital allowances come from the fixed asset register (section C, /fixed-assets). Echoes the register’s figure. Main pool WDV b/f.",
            "minimum": 0,
            "deprecated": true
          },
          "specialRatePoolBfPence": {
            "type": "integer",
            "description": "Deprecated: capital allowances come from the fixed asset register (section C, /fixed-assets). Echoes the register’s figure. Special rate pool WDV b/f.",
            "minimum": 0,
            "deprecated": true
          },
          "disposalProceedsPence": {
            "type": "integer",
            "description": "Deprecated: capital allowances come from the fixed asset register (section C, /fixed-assets). Echoes the register’s figure. Disposal values deducted from the pools.",
            "minimum": 0,
            "deprecated": true
          },
          "otherAdjustments": {
            "maxItems": 100,
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TaxAdjustmentInput"
            }
          },
          "lossesBroughtForward": {
            "description": "Last year’s losses carried forward (set by the roll forward). Absent: none.",
            "allOf": [
              {
                "$ref": "#/components/schemas/LossesBroughtForward"
              }
            ]
          }
        },
        "description": "Tax inputs the TB cannot give. Capital allowances are not among them: they come from the fixed asset register (C).",
        "required": [
          "associatedCompanies",
          "aiaPence",
          "mainPoolBfPence",
          "specialRatePoolBfPence",
          "disposalProceedsPence",
          "otherAdjustments"
        ]
      },
      "TaxAdjustmentLine": {
        "type": "object",
        "properties": {
          "description": {
            "type": "string"
          },
          "amountPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "reference": {
            "type": "string",
            "description": "Legislation or HMRC manual reference."
          }
        },
        "required": [
          "description",
          "amountPence",
          "reference"
        ]
      },
      "TaxAccountingPeriod": {
        "type": "object",
        "properties": {
          "start": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "end": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "days": {
            "type": "integer"
          },
          "adjustedProfitPence": {
            "type": "integer",
            "description": "Adjusted trading profit before capital allowances, apportioned by days (CTA 2010 s1172)."
          },
          "capitalAllowancesPence": {
            "type": "integer",
            "description": "Capital allowances for this period, net of balancing charges (CAA 2001 s6)."
          },
          "lossesUsedPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "taxableProfitsPence": {
            "type": "integer",
            "description": "Whole pounds (floored), in pence."
          },
          "roundedDownPence": {
            "type": "integer",
            "description": "Taken off by rounding down to whole pounds in this period."
          },
          "corporationTaxPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "marginalReliefPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "rateBand": {
            "type": "string"
          },
          "chargeLabel": {
            "type": "string"
          },
          "paymentDueDate": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31",
            "description": "9 months and 1 day after the accounting period ends (TMA 1970 s59D)."
          },
          "ct600Reference": {
            "type": "string",
            "description": "Which CT600 this is, e.g. \"CT600 1 of 2: 1 January 2025 to 31 December 2025\"."
          },
          "ct600DueDate": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31",
            "description": "FA 1998 Sch 18 para 14: set by the period of account, the same for each of its CT600s."
          }
        },
        "description": "One accounting period’s computation (CTA 2009 s10). A period of account over 12 months has two: the first 12 months and the rest.",
        "required": [
          "start",
          "end",
          "days",
          "adjustedProfitPence",
          "capitalAllowancesPence",
          "lossesUsedPence",
          "taxableProfitsPence",
          "roundedDownPence",
          "corporationTaxPence",
          "marginalReliefPence",
          "rateBand",
          "chargeLabel",
          "paymentDueDate",
          "ct600Reference",
          "ct600DueDate"
        ]
      },
      "DeferredTaxLine": {
        "type": "object",
        "properties": {
          "description": {
            "type": "string"
          },
          "netBookValuePence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "taxWrittenDownValuePence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "timingDifferencePence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          }
        },
        "required": [
          "description",
          "netBookValuePence",
          "taxWrittenDownValuePence",
          "timingDifferencePence"
        ]
      },
      "DeferredTax": {
        "type": "object",
        "properties": {
          "applies": {
            "type": "boolean"
          },
          "netBookValuePence": {
            "type": "integer",
            "description": "NBV of assets that attract allowances, per the register (C final per the TB when there is no register)."
          },
          "taxWrittenDownValuePence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "timingDifferencePence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "permanentDifferencePence": {
            "type": "integer",
            "description": "NBV of assets that never attract allowances (FRS 102 s29.10): no deferred tax."
          },
          "lines": {
            "description": "NBV against tax WDV by pool, single-asset pool or SBA asset, from the register.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/DeferredTaxLine"
            }
          },
          "rateBps": {
            "type": "integer"
          },
          "provisionPence": {
            "type": "integer",
            "description": "Provision required (liability positive)."
          },
          "openingPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "perTbPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "differencePence": {
            "type": "integer",
            "description": "Provision less TB: the deferred tax journal to post."
          },
          "journalAccountsMapped": {
            "type": "boolean",
            "description": "A deferred tax charge and provision are mapped in the TB, so the deferred tax journal can be posted."
          }
        },
        "required": [
          "applies",
          "netBookValuePence",
          "taxWrittenDownValuePence",
          "timingDifferencePence",
          "permanentDifferencePence",
          "lines",
          "rateBps",
          "provisionPence",
          "openingPence",
          "perTbPence",
          "differencePence",
          "journalAccountsMapped"
        ]
      },
      "TaxComputation": {
        "type": "object",
        "properties": {
          "applies": {
            "type": "boolean",
            "description": "Corporation tax applies (companies only)."
          },
          "error": {
            "type": [
              "string",
              "null"
            ]
          },
          "inputs": {
            "$ref": "#/components/schemas/TaxInputs"
          },
          "profitBeforeTaxPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "adjustments": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TaxAdjustmentLine"
            }
          },
          "additionsPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "aiaPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "mainPoolPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "mainPoolWdaPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "specialRatePoolWdaPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "balancingChargePence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "capitalAllowancesPence": {
            "type": "integer",
            "description": "Allowances before balancing charges, from the fixed asset register (C)."
          },
          "fixedAssetRegister": {
            "type": "boolean",
            "description": "Section C has a fixed asset register; without one no allowances are claimed."
          },
          "mainPoolBfPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "specialRatePoolBfPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "disposalValuesPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "firstYearAllowancesPence": {
            "type": "integer",
            "description": "Full expensing, special rate allowance and other first-year allowances."
          },
          "otherAllowancesPence": {
            "type": "integer",
            "description": "Single-asset pools, SBA and balancing allowances."
          },
          "mainPoolCfPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "specialRatePoolCfPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "lossesBfPence": {
            "type": "integer",
            "description": "Trading losses brought forward (both regimes)."
          },
          "lossesUsedPence": {
            "type": "integer",
            "description": "Losses brought forward set against this year’s profits."
          },
          "lossesCf": {
            "description": "Losses carried forward, including any trading loss of this year.",
            "allOf": [
              {
                "$ref": "#/components/schemas/LossesBroughtForward"
              }
            ]
          },
          "taxableProfitsPence": {
            "type": "integer",
            "description": "Whole pounds (floored), in pence."
          },
          "corporationTaxPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "marginalReliefPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "rateBand": {
            "type": "string",
            "description": "The rate band in plain words, e.g. \"Main rate 25%\" or \"Marginal relief applies\"."
          },
          "chargeLabel": {
            "type": "string",
            "description": "The tax before marginal relief, e.g. \"Corporation tax at 25% on £127,600\"."
          },
          "accountingPeriods": {
            "description": "One per accounting period; the totals above add them up.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TaxAccountingPeriod"
            }
          },
          "periodNote": {
            "type": [
              "string",
              "null"
            ],
            "description": "Explains a period of account over 12 months: the split, the apportionment and the rounding per period."
          },
          "journalAccountsMapped": {
            "type": "boolean",
            "description": "A corporation tax charge and creditor are mapped in the TB, so the tax journal can be posted."
          },
          "chargePerTbPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "differencePence": {
            "type": "integer",
            "description": "Computation less TB: the tax journal to post."
          },
          "deferred": {
            "$ref": "#/components/schemas/DeferredTax"
          },
          "warnings": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "lockedReason": {
            "type": [
              "string",
              "null"
            ],
            "description": "Why a preparer cannot change the computation now (section T reviewed)."
          },
          "inputsSetUp": {
            "type": "boolean",
            "description": "The preparer has saved the inputs (PUT …/tax/inputs) at least once, so the computation is set up."
          }
        },
        "required": [
          "applies",
          "error",
          "inputs",
          "profitBeforeTaxPence",
          "adjustments",
          "additionsPence",
          "aiaPence",
          "mainPoolPence",
          "mainPoolWdaPence",
          "specialRatePoolWdaPence",
          "balancingChargePence",
          "capitalAllowancesPence",
          "fixedAssetRegister",
          "mainPoolBfPence",
          "specialRatePoolBfPence",
          "disposalValuesPence",
          "firstYearAllowancesPence",
          "otherAllowancesPence",
          "mainPoolCfPence",
          "specialRatePoolCfPence",
          "lossesBfPence",
          "lossesUsedPence",
          "lossesCf",
          "taxableProfitsPence",
          "corporationTaxPence",
          "marginalReliefPence",
          "rateBand",
          "chargeLabel",
          "journalAccountsMapped",
          "chargePerTbPence",
          "differencePence",
          "deferred",
          "warnings",
          "lockedReason"
        ]
      },
      "SetTaxInputs": {
        "type": "object",
        "properties": {
          "associatedCompanies": {
            "type": "integer",
            "minimum": 0,
            "maximum": 1000
          },
          "otherAdjustments": {
            "maxItems": 100,
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TaxAdjustmentInput"
            }
          },
          "lossesBroughtForward": {
            "description": "Trading losses brought forward. Omitted: unchanged (the roll forward sets them).",
            "allOf": [
              {
                "$ref": "#/components/schemas/LossesBroughtForward"
              }
            ]
          },
          "aiaPence": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Deprecated and ignored: set in the fixed asset register (C).",
            "deprecated": true
          },
          "mainPoolBfPence": {
            "type": "integer",
            "description": "Deprecated and ignored: set in the fixed asset register settings (C).",
            "deprecated": true
          },
          "specialRatePoolBfPence": {
            "type": "integer",
            "description": "Deprecated and ignored: set in the fixed asset register settings (C).",
            "deprecated": true
          },
          "disposalProceedsPence": {
            "type": "integer",
            "description": "Deprecated and ignored: record disposals in the fixed asset register (C).",
            "deprecated": true
          }
        },
        "description": "Capital allowances are set in the fixed asset register (C), not here.",
        "required": [
          "associatedCompanies",
          "otherAdjustments"
        ]
      },
      "TaxJournalKind": {
        "type": "string",
        "enum": [
          "ct",
          "deferred"
        ]
      },
      "PreviewTaxJournal": {
        "type": "object",
        "properties": {
          "kind": {
            "allOf": [
              {
                "$ref": "#/components/schemas/TaxJournalKind"
              }
            ]
          }
        },
        "required": [
          "kind"
        ]
      },
      "TaxJournalPreview": {
        "type": "object",
        "properties": {
          "kind": {
            "allOf": [
              {
                "$ref": "#/components/schemas/TaxJournalKind"
              }
            ]
          },
          "date": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "narrative": {
            "type": "string"
          },
          "lines": {
            "description": "Empty when the TB already agrees with the computation.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/JournalLine"
            }
          },
          "replacesRef": {
            "type": [
              "string",
              "null"
            ],
            "description": "The earlier journal of this kind that posting would replace."
          },
          "replacesAmountPence": {
            "type": [
              "integer",
              "null"
            ],
            "description": "The total debits of the journal replaced."
          },
          "impact": {
            "$ref": "#/components/schemas/JournalImpact"
          },
          "blockedReason": {
            "type": [
              "string",
              "null"
            ],
            "description": "Why the caller can’t post it now (T reviewed and the caller is a preparer); null when they can."
          }
        },
        "description": "The tax journal that posting would make, without posting it.",
        "required": [
          "kind",
          "date",
          "narrative",
          "lines",
          "replacesRef",
          "replacesAmountPence",
          "impact",
          "blockedReason"
        ]
      },
      "PostTaxJournal": {
        "type": "object",
        "properties": {
          "kind": {
            "allOf": [
              {
                "$ref": "#/components/schemas/TaxJournalKind"
              }
            ]
          },
          "replace": {
            "type": "boolean",
            "description": "Replace an earlier tax journal of this kind (required when one exists)."
          }
        },
        "required": [
          "kind"
        ]
      },
      "TaxJournalResult": {
        "type": "object",
        "properties": {
          "journal": {
            "description": "Null when the TB already agrees.",
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/Journal"
              }
            ]
          },
          "replacedRef": {
            "type": [
              "string",
              "null"
            ]
          },
          "computation": {
            "$ref": "#/components/schemas/TaxComputation"
          }
        },
        "required": [
          "journal",
          "replacedRef",
          "computation"
        ]
      },
      "CapitalAllowanceRegime": {
        "type": "string",
        "enum": [
          "corporation-tax",
          "income-tax"
        ]
      },
      "PartYearPolicy": {
        "type": "string",
        "enum": [
          "full-year",
          "none",
          "time-apportioned"
        ],
        "description": "Depreciation in the year an asset is acquired."
      },
      "FixedAssetSettings": {
        "type": "object",
        "properties": {
          "acquisitionYear": {
            "description": "Depreciation in the year an asset is acquired.",
            "allOf": [
              {
                "$ref": "#/components/schemas/PartYearPolicy"
              }
            ]
          },
          "disposalYear": {
            "description": "Depreciation in the year an asset is disposed of.",
            "allOf": [
              {
                "$ref": "#/components/schemas/PartYearPolicy"
              }
            ]
          },
          "mainPoolBfPence": {
            "type": "integer",
            "description": "Main pool tax written down value brought forward.",
            "minimum": 0
          },
          "specialRatePoolBfPence": {
            "type": "integer",
            "description": "Special rate pool tax written down value brought forward.",
            "minimum": 0
          },
          "disposalProceedsCode": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 50,
            "description": "Account the fixed asset journal debits with disposal proceeds the TB does not yet show (the bank or debtor they went to, or a journal-only account). Left as it was when not sent."
          },
          "disposalAccountCode": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 50,
            "description": "The profit/loss on disposal account the fixed asset journal posts to: a TB account mapped there, or an account on the client’s chart of accounts with no balance yet. Null: the first account mapped to profit/loss on disposal. Left as it was when not sent."
          }
        },
        "description": "Part-year depreciation policy and the tax pools brought forward from last year.",
        "required": [
          "acquisitionYear",
          "disposalYear",
          "mainPoolBfPence",
          "specialRatePoolBfPence"
        ]
      },
      "FixedAssetDisposalCheck": {
        "type": "object",
        "properties": {
          "registerProfitPence": {
            "type": "integer",
            "description": "Register: proceeds less net book value of the assets disposed of in the period."
          },
          "tbProfitPence": {
            "type": "integer",
            "description": "Final TB: the profit/loss on disposal accounts, credit as profit."
          },
          "differencePence": {
            "type": "integer",
            "description": "Register less TB."
          },
          "proceedsPence": {
            "type": "integer",
            "description": "Disposal proceeds per the register."
          },
          "agreed": {
            "type": "boolean"
          }
        },
        "description": "Profit (positive) or loss (negative) on disposal per the register and per the final TB (profit/loss on disposal accounts in M). C is not done until they agree.",
        "required": [
          "registerProfitPence",
          "tbProfitPence",
          "differencePence",
          "proceedsPence",
          "agreed"
        ]
      },
      "DepreciationMethod": {
        "type": "string",
        "enum": [
          "straight-line",
          "straight-line-rate",
          "reducing-balance",
          "none"
        ]
      },
      "DepreciationPolicy": {
        "type": "object",
        "properties": {
          "method": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DepreciationMethod"
              }
            ]
          },
          "usefulLifeMonths": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 1,
            "maximum": 1200,
            "description": "Straight line: useful life in months."
          },
          "rateBasisPoints": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 1,
            "maximum": 10000,
            "description": "Straight-line rate or reducing balance, basis points (2500 = 25%)."
          }
        },
        "description": "Straight line over a useful life, straight line at a rate on cost, reducing balance at a rate, or none.",
        "required": [
          "method"
        ]
      },
      "TaxTreatment": {
        "type": "string",
        "enum": [
          "aia",
          "full-expensing",
          "first-year",
          "main-pool",
          "special-rate-pool",
          "single-asset-pool",
          "sba",
          "none"
        ],
        "description": "Default capital allowance treatment for the class’s assets."
      },
      "RateClass": {
        "type": "string",
        "enum": [
          "main",
          "special"
        ]
      },
      "FixedAssetClass": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "position": {
            "type": "integer"
          },
          "name": {
            "type": "string"
          },
          "costCode": {
            "type": [
              "string",
              "null"
            ],
            "description": "TB account for cost."
          },
          "depreciationCode": {
            "type": [
              "string",
              "null"
            ],
            "description": "TB account for accumulated depreciation."
          },
          "chargeCode": {
            "type": [
              "string",
              "null"
            ],
            "description": "TB account the depreciation charge goes to (default: the first admin depreciation account)."
          },
          "depreciation": {
            "$ref": "#/components/schemas/DepreciationPolicy"
          },
          "taxTreatment": {
            "description": "Default capital allowance treatment for the class’s assets.",
            "allOf": [
              {
                "$ref": "#/components/schemas/TaxTreatment"
              }
            ]
          },
          "rateClass": {
            "allOf": [
              {
                "$ref": "#/components/schemas/RateClass"
              }
            ]
          },
          "assetCount": {
            "type": "integer"
          }
        },
        "required": [
          "id",
          "position",
          "name",
          "costCode",
          "depreciationCode",
          "chargeCode",
          "depreciation",
          "taxTreatment",
          "rateClass",
          "assetCount"
        ]
      },
      "FixedAssetTax": {
        "type": "object",
        "properties": {
          "treatment": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/TaxTreatment"
              },
              {
                "type": "null"
              }
            ]
          },
          "rateClass": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/RateClass"
              },
              {
                "type": "null"
              }
            ]
          },
          "co2GramsPerKm": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 0,
            "maximum": 1000,
            "description": "Cars only (CAA 2001 s268A): CO₂ g/km. Cars never take AIA or full expensing."
          },
          "newAndUnused": {
            "type": [
              "boolean",
              "null"
            ],
            "description": "Needed for full expensing and first-year allowances."
          },
          "privateUsePercent": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 0,
            "maximum": 100,
            "description": "Sole traders and partnerships only (s205-s208)."
          },
          "sbaQualifyingCostPence": {
            "type": [
              "integer",
              "null"
            ],
            "description": "SBA: qualifying expenditure excluding land. Default cost.",
            "minimum": 0
          },
          "sbaFirstUseDate": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31",
            "description": "SBA: first brought into non-residential use. Default acquisition date."
          }
        },
        "description": "Overrides of the class’s tax treatment for one asset. Null or absent uses the class default."
      },
      "FixedAssetPool": {
        "type": "string",
        "enum": [
          "main",
          "special-rate",
          "single-asset",
          "sba",
          "none"
        ],
        "description": "The capital allowance pool the asset is in, as the computation decides it (a car by its CO₂ emissions, CAA 2001 s104AA)."
      },
      "FixedAsset": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "ref": {
            "type": "string",
            "example": "C-001"
          },
          "classId": {
            "type": "string",
            "format": "uuid"
          },
          "className": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "supplier": {
            "type": [
              "string",
              "null"
            ]
          },
          "invoiceRef": {
            "type": [
              "string",
              "null"
            ]
          },
          "acquisitionDate": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "costPence": {
            "type": "integer",
            "description": "Original cost."
          },
          "residualPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "broughtForward": {
            "type": "boolean",
            "description": "Held at the start of the period (b/f), as opposed to an addition."
          },
          "bfDepreciationPence": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Integer pence (GBP)."
          },
          "ownPolicy": {
            "type": "boolean",
            "description": "The asset has its own depreciation policy rather than the class’s."
          },
          "effectiveDepreciation": {
            "description": "The policy applied (the asset’s own, else the class’s).",
            "allOf": [
              {
                "$ref": "#/components/schemas/DepreciationPolicy"
              }
            ]
          },
          "tax": {
            "$ref": "#/components/schemas/FixedAssetTax"
          },
          "effectiveTreatment": {
            "description": "The treatment applied.",
            "allOf": [
              {
                "$ref": "#/components/schemas/TaxTreatment"
              }
            ]
          },
          "disposalDate": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31",
            "description": "Disposed of in the period on this date, or null if held."
          },
          "disposalProceedsPence": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Null while the proceeds are not known (a blocking check on C)."
          },
          "taxWdvBfPence": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Single-asset pool WDV brought forward."
          },
          "sbaClaimedBfPence": {
            "type": [
              "integer",
              "null"
            ],
            "description": "SBA claimed to date, brought forward."
          },
          "costBfPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "additionsPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "disposalsPence": {
            "type": "integer",
            "description": "Cost disposed of (positive)."
          },
          "costCfPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "depreciationBfPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "chargePence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "depreciationDisposalsPence": {
            "type": "integer",
            "description": "Depreciation eliminated on disposal (positive)."
          },
          "depreciationCfPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "nbvCfPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "profitOnDisposalPence": {
            "type": "integer",
            "description": "Proceeds less NBV disposed of; negative is a loss."
          },
          "claim": {
            "type": [
              "string",
              "null"
            ],
            "description": "Allowance claimed on this year’s expenditure: aia, full-expensing, special-rate-allowance, fya-40, fya-zero-emission-car, wda, sba or none."
          },
          "allowancePence": {
            "type": "integer",
            "description": "AIA or first-year allowance on this year’s expenditure."
          },
          "pool": {
            "description": "The capital allowance pool the asset is in, as the computation decides it (a car by its CO₂ emissions, CAA 2001 s104AA).",
            "allOf": [
              {
                "$ref": "#/components/schemas/FixedAssetPool"
              }
            ]
          }
        },
        "description": "One asset with this period’s movements per the register.",
        "required": [
          "id",
          "ref",
          "classId",
          "className",
          "description",
          "supplier",
          "invoiceRef",
          "acquisitionDate",
          "costPence",
          "residualPence",
          "broughtForward",
          "bfDepreciationPence",
          "ownPolicy",
          "effectiveDepreciation",
          "tax",
          "effectiveTreatment",
          "disposalDate",
          "disposalProceedsPence",
          "taxWdvBfPence",
          "sbaClaimedBfPence",
          "costBfPence",
          "additionsPence",
          "disposalsPence",
          "costCfPence",
          "depreciationBfPence",
          "chargePence",
          "depreciationDisposalsPence",
          "depreciationCfPence",
          "nbvCfPence",
          "profitOnDisposalPence",
          "claim",
          "allowancePence"
        ]
      },
      "FixedAssetMovement": {
        "type": "object",
        "properties": {
          "classId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "costBfPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "additionsPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "disposalsPence": {
            "type": "integer",
            "description": "Positive."
          },
          "costCfPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "depreciationBfPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "chargePence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "depreciationDisposalsPence": {
            "type": "integer",
            "description": "Positive."
          },
          "depreciationCfPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "nbvBfPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "nbvCfPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "proceedsPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "profitOnDisposalPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          }
        },
        "description": "Cost and depreciation b/f, movements and c/f for an asset class (or the total).",
        "required": [
          "classId",
          "name",
          "costBfPence",
          "additionsPence",
          "disposalsPence",
          "costCfPence",
          "depreciationBfPence",
          "chargePence",
          "depreciationDisposalsPence",
          "depreciationCfPence",
          "nbvBfPence",
          "nbvCfPence",
          "proceedsPence",
          "profitOnDisposalPence"
        ]
      },
      "FixedAssetReconciliationLine": {
        "type": "object",
        "properties": {
          "classId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid",
            "description": "Null for C accounts no class claims."
          },
          "name": {
            "type": "string"
          },
          "costCode": {
            "type": [
              "string",
              "null"
            ]
          },
          "depreciationCode": {
            "type": [
              "string",
              "null"
            ]
          },
          "registerCostPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "registerDepreciationPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "registerNbvPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "tbCostPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "tbDepreciationPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "tbNbvPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "differenceCostPence": {
            "type": "integer",
            "description": "Register less TB."
          },
          "differenceDepreciationPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "differenceNbvPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "agreed": {
            "type": "boolean"
          },
          "openingIssue": {
            "type": [
              "string",
              "null"
            ],
            "description": "Why the opening position does not agree for this class (for example cost and depreciation held in one TB account), and the fix. The fixed asset journal does not post it."
          }
        },
        "description": "Register against the final TB for one class (cost and accumulated depreciation both positive).",
        "required": [
          "classId",
          "name",
          "costCode",
          "depreciationCode",
          "registerCostPence",
          "registerDepreciationPence",
          "registerNbvPence",
          "tbCostPence",
          "tbDepreciationPence",
          "tbNbvPence",
          "differenceCostPence",
          "differenceDepreciationPence",
          "differenceNbvPence",
          "agreed",
          "openingIssue"
        ]
      },
      "FixedAssetReconciliation": {
        "type": "object",
        "properties": {
          "lines": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/FixedAssetReconciliationLine"
            }
          },
          "agreed": {
            "type": "boolean",
            "description": "Blocking check on C: every class agrees to the penny."
          },
          "differenceNbvPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          }
        },
        "required": [
          "lines",
          "agreed",
          "differenceNbvPence"
        ]
      },
      "CapitalAllowancePoolKind": {
        "type": "string",
        "enum": [
          "main",
          "special-rate"
        ]
      },
      "CapitalAllowancePool": {
        "type": "object",
        "properties": {
          "pool": {
            "allOf": [
              {
                "$ref": "#/components/schemas/CapitalAllowancePoolKind"
              }
            ]
          },
          "writtenDownValueBfPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "additionsPence": {
            "type": "integer",
            "description": "Expenditure added to the pool (after AIA and first-year allowances)."
          },
          "aiaClaimedPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "disposalValuesPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "balanceBeforeAllowancesPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "wdaRateBps": {
            "type": "integer"
          },
          "writingDownAllowancePence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "smallPoolAllowancePence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "balancingAllowancePence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "balancingChargePence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "writtenDownValueCfPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          }
        },
        "required": [
          "pool",
          "writtenDownValueBfPence",
          "additionsPence",
          "aiaClaimedPence",
          "disposalValuesPence",
          "balanceBeforeAllowancesPence",
          "wdaRateBps",
          "writingDownAllowancePence",
          "smallPoolAllowancePence",
          "balancingAllowancePence",
          "balancingChargePence",
          "writtenDownValueCfPence"
        ]
      },
      "SingleAssetPool": {
        "type": "object",
        "properties": {
          "assetId": {
            "type": "string",
            "format": "uuid"
          },
          "ref": {
            "type": "string"
          },
          "businessUsePercent": {
            "type": "integer"
          },
          "writtenDownValueBfPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "additionsPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "disposalValuePence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "allowanceBeforeRestrictionPence": {
            "type": "integer",
            "description": "Allowances on the whole pool, before the private-use restriction (CAA 2001 s207)."
          },
          "aiaClaimedPence": {
            "type": "integer",
            "description": "Of allowanceBeforeRestrictionPence, the Annual Investment Allowance. Included in the period’s aiaClaimedPence."
          },
          "allowancesClaimedPence": {
            "type": "integer",
            "description": "Business share."
          },
          "balancingChargePence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "writtenDownValueCfPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          }
        },
        "required": [
          "assetId",
          "ref",
          "businessUsePercent",
          "writtenDownValueBfPence",
          "additionsPence",
          "disposalValuePence",
          "allowanceBeforeRestrictionPence",
          "aiaClaimedPence",
          "allowancesClaimedPence",
          "balancingChargePence",
          "writtenDownValueCfPence"
        ]
      },
      "StructuresAndBuildingsAllowance": {
        "type": "object",
        "properties": {
          "assetId": {
            "type": "string",
            "format": "uuid"
          },
          "ref": {
            "type": "string"
          },
          "qualifyingCostPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "claimedBfPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "allowancePence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "claimedCfPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          }
        },
        "required": [
          "assetId",
          "ref",
          "qualifyingCostPence",
          "claimedBfPence",
          "allowancePence",
          "claimedCfPence"
        ]
      },
      "CapitalAllowancePeriod": {
        "type": "object",
        "properties": {
          "periodStart": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "periodEnd": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "aiaMaximumPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "aiaClaimedPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "firstYearAllowancesPence": {
            "type": "integer",
            "description": "Full expensing, special rate allowance, 40% FYA and zero-emission car FYA."
          },
          "mainPool": {
            "$ref": "#/components/schemas/CapitalAllowancePool"
          },
          "specialRatePool": {
            "$ref": "#/components/schemas/CapitalAllowancePool"
          },
          "singleAssetPools": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SingleAssetPool"
            }
          },
          "structuresAndBuildings": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/StructuresAndBuildingsAllowance"
            }
          },
          "totalAllowancesPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "totalBalancingChargesPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "netAllowancesPence": {
            "type": "integer",
            "description": "Allowances less balancing charges."
          }
        },
        "description": "Capital allowances for one chargeable period (CAA 2001; CTA 2009 s10 for a company’s long period of account).",
        "required": [
          "periodStart",
          "periodEnd",
          "aiaMaximumPence",
          "aiaClaimedPence",
          "firstYearAllowancesPence",
          "mainPool",
          "specialRatePool",
          "singleAssetPools",
          "structuresAndBuildings",
          "totalAllowancesPence",
          "totalBalancingChargesPence",
          "netAllowancesPence"
        ]
      },
      "FixedAssetTimingDifference": {
        "type": "object",
        "properties": {
          "key": {
            "type": "string"
          },
          "label": {
            "type": "string"
          },
          "nbvPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "taxWrittenDownValuePence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "timingDifferencePence": {
            "type": "integer",
            "description": "Positive: accelerated capital allowances (a liability)."
          },
          "permanentDifferencePence": {
            "type": "integer",
            "description": "NBV that never attracts allowances: no deferred tax."
          }
        },
        "description": "Accounting NBV against tax WDV by pool, single-asset pool or SBA asset (FRS 102 s29).",
        "required": [
          "key",
          "label",
          "nbvPence",
          "taxWrittenDownValuePence",
          "timingDifferencePence",
          "permanentDifferencePence"
        ]
      },
      "FixedAssetDeferredTax": {
        "type": "object",
        "properties": {
          "lines": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/FixedAssetTimingDifference"
            }
          },
          "totalTimingDifferencePence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "totalPermanentDifferencePence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          }
        },
        "required": [
          "lines",
          "totalTimingDifferencePence",
          "totalPermanentDifferencePence"
        ]
      },
      "FixedAssetIssue": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string"
          },
          "assetId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "message": {
            "type": "string"
          }
        },
        "required": [
          "code",
          "assetId",
          "message"
        ]
      },
      "FixedAssetJournalLine": {
        "type": "object",
        "properties": {
          "accountCode": {
            "type": "string"
          },
          "accountName": {
            "type": [
              "string",
              "null"
            ]
          },
          "debitPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "creditPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          }
        },
        "required": [
          "accountCode",
          "accountName",
          "debitPence",
          "creditPence"
        ]
      },
      "FixedAssetJournalProposal": {
        "type": "object",
        "properties": {
          "lines": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/FixedAssetJournalLine"
            }
          },
          "unresolved": {
            "description": "Differences the journal cannot put right; post those by hand.",
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "existingRef": {
            "type": [
              "string",
              "null"
            ],
            "description": "The fixed asset journal already posted, which posting again replaces."
          }
        },
        "description": "The journal that brings the TB to the register: disposals derecognised and depreciation charged.",
        "required": [
          "lines",
          "unresolved",
          "existingRef"
        ]
      },
      "FixedAssetDefaultChargeAccount": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "inTb": {
            "type": "boolean",
            "description": "False for an account on the client’s chart of accounts with no balance in this TB yet: the fixed asset journal posts to it under its own code."
          }
        },
        "description": "Where the depreciation charge goes for a class with no charge account of its own.",
        "required": [
          "code",
          "name",
          "inTb"
        ]
      },
      "FixedAssetRegister": {
        "type": "object",
        "properties": {
          "inUse": {
            "type": "boolean",
            "description": "Any class or asset has been entered."
          },
          "error": {
            "type": [
              "string",
              "null"
            ],
            "description": "Why the register could not be computed."
          },
          "regime": {
            "allOf": [
              {
                "$ref": "#/components/schemas/CapitalAllowanceRegime"
              }
            ]
          },
          "settings": {
            "$ref": "#/components/schemas/FixedAssetSettings"
          },
          "disposals": {
            "$ref": "#/components/schemas/FixedAssetDisposalCheck"
          },
          "classes": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/FixedAssetClass"
            }
          },
          "assets": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/FixedAsset"
            }
          },
          "movements": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/FixedAssetMovement"
            }
          },
          "total": {
            "$ref": "#/components/schemas/FixedAssetMovement"
          },
          "reconciliation": {
            "$ref": "#/components/schemas/FixedAssetReconciliation"
          },
          "capitalAllowances": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CapitalAllowancePeriod"
            }
          },
          "deferredTax": {
            "description": "Empty until the register can be computed.",
            "allOf": [
              {
                "$ref": "#/components/schemas/FixedAssetDeferredTax"
              }
            ]
          },
          "issues": {
            "description": "Treatments the engines changed, and why (e.g. AIA refused on a car).",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/FixedAssetIssue"
            }
          },
          "journal": {
            "$ref": "#/components/schemas/FixedAssetJournalProposal"
          },
          "defaultChargeAccount": {
            "description": "Null when neither the TB nor the client’s chart of accounts has an account mapped to admin depreciation: add one in the client’s books.",
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/FixedAssetDefaultChargeAccount"
              }
            ]
          },
          "lockedReason": {
            "type": [
              "string",
              "null"
            ],
            "description": "Why you cannot change the register now (C reviewed, or you are not its preparer)."
          }
        },
        "description": "Section C: the register, depreciation per policy, capital allowances, the TB reconciliation and NBV against tax WDV.",
        "required": [
          "inUse",
          "error",
          "regime",
          "settings",
          "classes",
          "assets",
          "movements",
          "total",
          "reconciliation",
          "capitalAllowances",
          "deferredTax",
          "issues",
          "journal",
          "defaultChargeAccount",
          "lockedReason"
        ]
      },
      "CreateFixedAssetClass": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "maxLength": 100
          },
          "costCode": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 50
          },
          "depreciationCode": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 50
          },
          "chargeCode": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 50
          },
          "depreciation": {
            "$ref": "#/components/schemas/DepreciationPolicy"
          },
          "taxTreatment": {
            "description": "Default aia.",
            "allOf": [
              {
                "$ref": "#/components/schemas/TaxTreatment"
              }
            ]
          },
          "rateClass": {
            "description": "Default main.",
            "allOf": [
              {
                "$ref": "#/components/schemas/RateClass"
              }
            ]
          }
        },
        "required": [
          "name",
          "depreciation"
        ]
      },
      "UpdateFixedAssetClass": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "maxLength": 100
          },
          "position": {
            "type": "integer",
            "minimum": 1
          },
          "costCode": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 50
          },
          "depreciationCode": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 50
          },
          "chargeCode": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 50
          },
          "depreciation": {
            "$ref": "#/components/schemas/DepreciationPolicy"
          },
          "taxTreatment": {
            "allOf": [
              {
                "$ref": "#/components/schemas/TaxTreatment"
              }
            ]
          },
          "rateClass": {
            "allOf": [
              {
                "$ref": "#/components/schemas/RateClass"
              }
            ]
          }
        },
        "description": "Only the fields given change."
      },
      "CreateFixedAsset": {
        "type": "object",
        "properties": {
          "classId": {
            "type": "string",
            "format": "uuid"
          },
          "ref": {
            "type": "string",
            "maxLength": 20,
            "description": "W/P ref; default the next C-nnn."
          },
          "description": {
            "type": "string",
            "maxLength": 200
          },
          "supplier": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 200
          },
          "invoiceRef": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 100
          },
          "acquisitionDate": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "costPence": {
            "type": "integer",
            "description": "Integer pence (GBP).",
            "minimum": 0
          },
          "residualPence": {
            "type": "integer",
            "description": "Integer pence (GBP).",
            "minimum": 0
          },
          "bfDepreciationPence": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Set for an asset held at the start of the period: accumulated depreciation b/f. Null (or absent) for an addition.",
            "minimum": 0
          },
          "depreciation": {
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/DepreciationPolicy"
              }
            ]
          },
          "tax": {
            "$ref": "#/components/schemas/FixedAssetTax"
          },
          "taxWdvBfPence": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Integer pence (GBP).",
            "minimum": 0
          },
          "sbaClaimedBfPence": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Integer pence (GBP).",
            "minimum": 0
          }
        },
        "required": [
          "classId",
          "description",
          "acquisitionDate",
          "costPence"
        ]
      },
      "UpdateFixedAsset": {
        "type": "object",
        "properties": {
          "classId": {
            "type": "string",
            "format": "uuid"
          },
          "ref": {
            "type": "string",
            "maxLength": 20
          },
          "description": {
            "type": "string",
            "maxLength": 200
          },
          "supplier": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 200
          },
          "invoiceRef": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 100
          },
          "acquisitionDate": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "costPence": {
            "type": "integer",
            "description": "Integer pence (GBP).",
            "minimum": 0
          },
          "residualPence": {
            "type": "integer",
            "description": "Integer pence (GBP).",
            "minimum": 0
          },
          "bfDepreciationPence": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Integer pence (GBP).",
            "minimum": 0
          },
          "depreciation": {
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/DepreciationPolicy"
              }
            ]
          },
          "tax": {
            "$ref": "#/components/schemas/FixedAssetTax"
          },
          "taxWdvBfPence": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Integer pence (GBP).",
            "minimum": 0
          },
          "sbaClaimedBfPence": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Integer pence (GBP).",
            "minimum": 0
          }
        },
        "description": "Only the fields given change."
      },
      "FixedAssetDisposalOutcome": {
        "type": "object",
        "properties": {
          "nbvAtDisposalPence": {
            "type": "integer",
            "description": "Cost less accumulated depreciation at the disposal date."
          },
          "proceedsPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "profitOnDisposalPence": {
            "type": "integer",
            "description": "Proceeds less NBV: positive a profit, negative a loss."
          },
          "disposalValuePence": {
            "type": "integer",
            "description": "Deducted from the pool (or the asset’s single-asset pool): the proceeds capped at cost (CAA 2001 ss61–62)."
          },
          "balancingAllowancePence": {
            "type": "integer",
            "description": "Balancing allowance the disposal gives (CAA 2001 s55; single-asset pools s206)."
          },
          "balancingChargePence": {
            "type": "integer",
            "description": "Balancing charge the disposal causes, including the relevant proportion on full expensing (CA23174AD)."
          }
        },
        "required": [
          "nbvAtDisposalPence",
          "proceedsPence",
          "profitOnDisposalPence",
          "disposalValuePence",
          "balancingAllowancePence",
          "balancingChargePence"
        ]
      },
      "FixedAssetTotals": {
        "type": "object",
        "properties": {
          "depreciationChargePence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "capitalAllowancesPence": {
            "type": "integer",
            "description": "Capital allowances for the period (all chargeable periods), before balancing charges."
          },
          "balancingChargesPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "nbvCfPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "profitOnDisposalPence": {
            "type": "integer",
            "description": "Profit (positive) or loss (negative) on disposal."
          }
        },
        "description": "The register’s figures for the period, before or after the change previewed.",
        "required": [
          "depreciationChargePence",
          "capitalAllowancesPence",
          "balancingChargesPence",
          "nbvCfPence",
          "profitOnDisposalPence"
        ]
      },
      "FixedAssetPreview": {
        "type": "object",
        "properties": {
          "asset": {
            "description": "The asset as the register would show it.",
            "allOf": [
              {
                "$ref": "#/components/schemas/FixedAsset"
              }
            ]
          },
          "error": {
            "type": [
              "string",
              "null"
            ],
            "description": "Why the register could not be computed with this change."
          },
          "pool": {
            "description": "The capital allowance pool the asset is in.",
            "oneOf": [
              {
                "$ref": "#/components/schemas/FixedAssetPool"
              },
              {
                "type": "null"
              }
            ]
          },
          "depreciationChargePence": {
            "type": "integer",
            "description": "This asset’s depreciation charge for the period."
          },
          "nbvCfPence": {
            "type": "integer",
            "description": "This asset’s net book value carried forward."
          },
          "allowancePence": {
            "type": "integer",
            "description": "AIA, first-year allowance or full expensing on this asset’s cost this period, before any private-use restriction. Writing down allowances are in the totals."
          },
          "claim": {
            "type": [
              "string",
              "null"
            ],
            "description": "The allowance claimed on its cost, e.g. \"aia\", \"full-expensing\", \"pool\"."
          },
          "disposal": {
            "description": "Set when the asset is disposed of in the period.",
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/FixedAssetDisposalOutcome"
              }
            ]
          },
          "before": {
            "$ref": "#/components/schemas/FixedAssetTotals"
          },
          "after": {
            "$ref": "#/components/schemas/FixedAssetTotals"
          },
          "issues": {
            "description": "Notes from the engines about this asset, e.g. a disposal value capped at cost.",
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "journal": {
            "description": "The fixed asset journal the register would then propose.",
            "allOf": [
              {
                "$ref": "#/components/schemas/FixedAssetJournalProposal"
              }
            ]
          },
          "lockedReason": {
            "type": [
              "string",
              "null"
            ],
            "description": "Why you could not save it now (C reviewed)."
          }
        },
        "description": "What saving an asset or a disposal would do, worked by the same engines as the register. Nothing is stored.",
        "required": [
          "asset",
          "error",
          "pool",
          "depreciationChargePence",
          "nbvCfPence",
          "allowancePence",
          "claim",
          "disposal",
          "before",
          "after",
          "issues",
          "journal",
          "lockedReason"
        ]
      },
      "FixedAssetDisposal": {
        "type": "object",
        "properties": {
          "date": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "proceedsPence": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Null while the proceeds are not known (a blocking check on C). Nil for an asset scrapped.",
            "minimum": 0
          }
        },
        "required": [
          "date",
          "proceedsPence"
        ]
      },
      "FixedAssetJournalPreview": {
        "type": "object",
        "properties": {
          "date": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31",
            "description": "The journal date: the period end."
          },
          "narrative": {
            "type": "string"
          },
          "lines": {
            "description": "Empty when the TB already agrees with the register.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/FixedAssetJournalLine"
            }
          },
          "unresolved": {
            "description": "Differences the journal cannot put right; posting is refused (422) until they are dealt with by hand.",
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "replacesRef": {
            "type": [
              "string",
              "null"
            ],
            "description": "The fixed asset journal already posted, which posting would replace (it is deleted; its number is never reused)."
          },
          "replacesAmountPence": {
            "type": [
              "integer",
              "null"
            ],
            "description": "The total debits of the journal replaced, in integer pence."
          },
          "impact": {
            "$ref": "#/components/schemas/JournalImpact"
          },
          "blockedReason": {
            "type": [
              "string",
              "null"
            ],
            "description": "Why the caller can’t post it now (C reviewed and the caller is a preparer); null when they can."
          }
        },
        "description": "What posting the fixed asset journal would do. Nothing is saved.",
        "required": [
          "date",
          "narrative",
          "lines",
          "unresolved",
          "replacesRef",
          "replacesAmountPence",
          "impact",
          "blockedReason"
        ]
      },
      "PostFixedAssetJournal": {
        "type": "object",
        "properties": {
          "replace": {
            "type": "boolean",
            "description": "Replace the earlier fixed asset journal (required when one exists)."
          }
        }
      },
      "FixedAssetJournalResult": {
        "type": "object",
        "properties": {
          "journal": {
            "description": "Null when the TB already agrees.",
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/Journal"
              }
            ]
          },
          "replacedRef": {
            "type": [
              "string",
              "null"
            ]
          },
          "register": {
            "$ref": "#/components/schemas/FixedAssetRegister"
          }
        },
        "required": [
          "journal",
          "replacedRef",
          "register"
        ]
      },
      "RollForwardSource": {
        "type": "object",
        "properties": {
          "engagementId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid",
            "description": "Null once that engagement was deleted."
          },
          "periodStart": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "periodEnd": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "status": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/EngagementStatus"
              },
              {
                "type": "null"
              }
            ]
          }
        },
        "description": "The engagement brought forward from.",
        "required": [
          "engagementId",
          "periodStart",
          "periodEnd",
          "status"
        ]
      },
      "RollForwardParts": {
        "type": "object",
        "properties": {
          "priorYearFigures": {
            "type": "boolean"
          },
          "mappings": {
            "type": "boolean"
          },
          "fixedAssets": {
            "type": "boolean"
          },
          "taxBroughtForward": {
            "type": "boolean"
          },
          "notes": {
            "type": "boolean"
          }
        },
        "description": "What was brought forward.",
        "required": [
          "priorYearFigures",
          "mappings",
          "fixedAssets",
          "taxBroughtForward",
          "notes"
        ]
      },
      "RolledPriorYearFigures": {
        "type": "object",
        "properties": {
          "accounts": {
            "type": "integer",
            "minimum": 0
          },
          "profitPence": {
            "type": "integer",
            "description": "Last year’s profit after tax per its final TB (a loss negative)."
          }
        },
        "required": [
          "accounts",
          "profitPence"
        ]
      },
      "RolledFixedAssets": {
        "type": "object",
        "properties": {
          "classes": {
            "type": "integer",
            "minimum": 0
          },
          "assets": {
            "type": "integer",
            "minimum": 0
          },
          "costPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "depreciationPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "nbvPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          }
        },
        "required": [
          "classes",
          "assets",
          "costPence",
          "depreciationPence",
          "nbvPence"
        ]
      },
      "RolledSelfAssessment": {
        "type": "object",
        "properties": {
          "lossesPence": {
            "type": "integer",
            "description": "Trading losses carried forward (ITA 2007 s83)."
          },
          "overlapReliefPence": {
            "type": "integer",
            "description": "Overlap relief not yet used (nil after 2023/24, FA 2022 Sch 1)."
          },
          "transitionProfitPence": {
            "type": "integer",
            "description": "Transition profit still being spread."
          },
          "partners": {
            "type": "integer",
            "minimum": 0
          }
        },
        "description": "Sole traders, partnerships and LLPs: totals across partners for a partnership.",
        "required": [
          "lossesPence",
          "overlapReliefPence",
          "transitionProfitPence",
          "partners"
        ]
      },
      "RolledTax": {
        "type": "object",
        "properties": {
          "mainPoolPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "specialRatePoolPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "lossesPre2017Pence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "lossesPost2017Pence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "deferredTaxPence": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Last year’s deferred tax provision per its computation (liability positive); null when it did not apply."
          },
          "selfAssessment": {
            "description": "Null for a company.",
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/RolledSelfAssessment"
              }
            ]
          }
        },
        "required": [
          "mainPoolPence",
          "specialRatePoolPence",
          "lossesPre2017Pence",
          "lossesPost2017Pence",
          "deferredTaxPence",
          "selfAssessment"
        ]
      },
      "RollForwardSummary": {
        "type": "object",
        "properties": {
          "priorYearFigures": {
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/RolledPriorYearFigures"
              }
            ]
          },
          "mappings": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Mappings added."
          },
          "notes": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Variance notes brought forward as hints."
          },
          "fixedAssets": {
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/RolledFixedAssets"
              }
            ]
          },
          "tax": {
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/RolledTax"
              }
            ]
          },
          "warnings": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        },
        "description": "What was brought forward; null for a part that was not.",
        "required": [
          "priorYearFigures",
          "mappings",
          "notes",
          "fixedAssets",
          "tax",
          "warnings"
        ]
      },
      "RollForwardPart": {
        "type": "string",
        "enum": [
          "priorYearFigures",
          "mappings",
          "fixedAssets",
          "taxBroughtForward",
          "notes"
        ],
        "description": "The parts that changed."
      },
      "RollForward": {
        "type": "object",
        "properties": {
          "rolledForward": {
            "type": "boolean"
          },
          "source": {
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/RollForwardSource"
              }
            ]
          },
          "rolledAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "rolledBy": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "options": {
            "$ref": "#/components/schemas/RollForwardParts"
          },
          "summary": {
            "$ref": "#/components/schemas/RollForwardSummary"
          },
          "priorChanged": {
            "type": "boolean",
            "description": "The prior year changed after it was brought forward (its content fingerprint differs): re-roll to take the change."
          },
          "changedParts": {
            "type": "array",
            "description": "The parts that changed.",
            "items": {
              "$ref": "#/components/schemas/RollForwardPart"
            }
          },
          "changes": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "available": {
            "description": "The engagement a (re-)roll would bring forward from now.",
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/RollForwardSource"
              }
            ]
          },
          "reroll": {
            "description": "Re-roll from prior year: only while the file is Not started or Preparing.",
            "allOf": [
              {
                "$ref": "#/components/schemas/GuardResult"
              }
            ]
          }
        },
        "description": "The year-end roll forward: what was brought forward from the prior year, and whether the prior year changed since.",
        "required": [
          "rolledForward",
          "source",
          "rolledAt",
          "rolledBy",
          "options",
          "summary",
          "priorChanged",
          "changedParts",
          "changes",
          "available",
          "reroll"
        ]
      },
      "SaEntity": {
        "type": "string",
        "enum": [
          "sole_trader",
          "partnership",
          "llp"
        ]
      },
      "Sa103ExpenseCategory": {
        "type": "string",
        "enum": [
          "costOfGoods",
          "constructionSubcontractors",
          "wagesAndStaffCosts",
          "carVanAndTravel",
          "rentRatesPowerAndInsurance",
          "repairsAndMaintenance",
          "phoneFaxStationeryAndOffice",
          "advertisingAndBusinessEntertainment",
          "interestOnBankAndOtherLoans",
          "bankCreditCardAndFinancialCharges",
          "irrecoverableDebts",
          "accountancyLegalAndProfessional",
          "depreciationAndLossOnSale",
          "otherBusinessExpenses"
        ],
        "description": "SA103 expense line; null uses Tolvi’s suggestion."
      },
      "SaAccountTreatment": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string",
            "description": "Account code in the TB."
          },
          "category": {
            "description": "SA103 expense line; null uses Tolvi’s suggestion.",
            "oneOf": [
              {
                "$ref": "#/components/schemas/Sa103ExpenseCategory"
              },
              {
                "type": "null"
              }
            ]
          },
          "disallowablePence": {
            "type": "integer",
            "description": "Disallowable outright (fines, capital items). Depreciation and entertaining (M.dis) are always disallowed in full."
          },
          "privateUsePercent": {
            "type": [
              "number",
              "null"
            ],
            "minimum": 0,
            "maximum": 100,
            "description": "Private-use share of the rest, in per cent; null = not considered yet (0 means none)."
          }
        },
        "required": [
          "code",
          "category",
          "disallowablePence",
          "privateUsePercent"
        ]
      },
      "SaAdjustmentInput": {
        "type": "object",
        "properties": {
          "description": {
            "type": "string"
          },
          "amountPence": {
            "type": "integer",
            "description": "Positive adds back, negative deducts."
          }
        },
        "required": [
          "description",
          "amountPence"
        ]
      },
      "TradingAllowanceChoice": {
        "type": "string",
        "enum": [
          "auto",
          "claim",
          "none"
        ],
        "description": "Sole traders: auto claims the £1,000 trading allowance when it gives a lower profit. Never available for partnership income."
      },
      "SaOtherPeriod": {
        "type": "object",
        "properties": {
          "start": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "end": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "profitPence": {
            "type": "integer",
            "description": "Tax-adjusted profit after capital allowances (negative for a loss)."
          },
          "provisional": {
            "type": "boolean",
            "description": "A provisional figure for a period not yet drawn up, to be amended once known."
          }
        },
        "required": [
          "start",
          "end",
          "profitPence",
          "provisional"
        ]
      },
      "SaPartnerKind": {
        "type": "string",
        "enum": [
          "individual",
          "company"
        ],
        "description": "A company partner (or LLP corporate member) is charged to corporation tax on its share; no income tax working is done for it."
      },
      "SaPartner": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "maxLength": 40,
            "description": "Your own short id for the partner, used in the arrangements."
          },
          "name": {
            "type": "string"
          },
          "kind": {
            "description": "A company partner (or LLP corporate member) is charged to corporation tax on its share; no income tax working is done for it.",
            "allOf": [
              {
                "$ref": "#/components/schemas/SaPartnerKind"
              }
            ]
          },
          "joined": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31"
          },
          "left": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31"
          },
          "overlapReliefPence": {
            "type": "integer",
            "description": "Overlap relief brought forward, used in 2023/24."
          },
          "transitionProfitPence": {
            "type": "integer",
            "description": "The partner’s transition profit from 2023/24, spread over five years."
          },
          "lossesBroughtForwardPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          }
        },
        "required": [
          "id",
          "name",
          "kind",
          "joined",
          "left",
          "overlapReliefPence",
          "transitionProfitPence",
          "lossesBroughtForwardPence"
        ]
      },
      "SaPartnerShare": {
        "type": "object",
        "properties": {
          "partnerId": {
            "type": "string"
          },
          "ratio": {
            "type": "integer",
            "minimum": 0,
            "description": "Residual profit-sharing ratio, as whole-number weights (e.g. 50/35/15)."
          },
          "salaryPence": {
            "type": "integer",
            "description": "Annual salary (prior share)."
          },
          "interestPence": {
            "type": "integer",
            "description": "Annual interest on capital."
          }
        },
        "required": [
          "partnerId",
          "ratio",
          "salaryPence",
          "interestPence"
        ]
      },
      "SaArrangement": {
        "type": "object",
        "properties": {
          "from": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31",
            "description": "In force from this date until the next arrangement starts."
          },
          "shares": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SaPartnerShare"
            }
          }
        },
        "required": [
          "from",
          "shares"
        ]
      },
      "SelfAssessmentInputs": {
        "type": "object",
        "properties": {
          "accounts": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SaAccountTreatment"
            }
          },
          "goodsForOwnUsePence": {
            "type": "integer",
            "description": "Goods taken for own use, at selling price (ITTOIA 2005 s172B)."
          },
          "otherAdjustments": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SaAdjustmentInput"
            }
          },
          "tradingAllowance": {
            "description": "Sole traders: auto claims the £1,000 trading allowance when it gives a lower profit. Never available for partnership income.",
            "allOf": [
              {
                "$ref": "#/components/schemas/TradingAllowanceChoice"
              }
            ]
          },
          "lateAccountingDates": {
            "type": "boolean",
            "description": "Treat a 31 March to 4 April year end as 5 April (ITTOIA 2005 s202B)."
          },
          "commencementDate": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31"
          },
          "cessationDate": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31"
          },
          "otherPeriods": {
            "description": "Other periods of account needed to apportion profit to the tax year (last year, or a provisional figure for next year).",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SaOtherPeriod"
            }
          },
          "overlapReliefPence": {
            "type": "integer",
            "description": "Sole trader: overlap relief brought forward (used in 2023/24)."
          },
          "transitionProfitPence": {
            "type": "integer",
            "description": "Sole trader: transition profit from 2023/24, spread over five years."
          },
          "lossesBroughtForwardPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "partners": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SaPartner"
            }
          },
          "arrangements": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SaArrangement"
            }
          }
        },
        "required": [
          "accounts",
          "goodsForOwnUsePence",
          "otherAdjustments",
          "tradingAllowance",
          "lateAccountingDates",
          "commencementDate",
          "cessationDate",
          "otherPeriods",
          "overlapReliefPence",
          "transitionProfitPence",
          "lossesBroughtForwardPence",
          "partners",
          "arrangements"
        ]
      },
      "SaDateRange": {
        "type": "object",
        "properties": {
          "start": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "end": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          }
        },
        "required": [
          "start",
          "end"
        ]
      },
      "SaAccountRow": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "lineId": {
            "type": "string"
          },
          "amountPence": {
            "type": "integer",
            "description": "Final TB balance, debit positive."
          },
          "category": {
            "allOf": [
              {
                "$ref": "#/components/schemas/Sa103ExpenseCategory"
              }
            ]
          },
          "categorySuggested": {
            "type": "boolean",
            "description": "The category is Tolvi’s suggestion, not the preparer’s."
          },
          "disallowablePence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "privateUsePercent": {
            "type": [
              "number",
              "null"
            ]
          },
          "privateUsePence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "allowablePence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "privateUseUnrecorded": {
            "type": "boolean",
            "description": "The account usually has some private use (motor, phone, use of home) and none is recorded."
          }
        },
        "required": [
          "code",
          "name",
          "lineId",
          "amountPence",
          "category",
          "categorySuggested",
          "disallowablePence",
          "privateUsePercent",
          "privateUsePence",
          "allowablePence",
          "privateUseUnrecorded"
        ]
      },
      "SaLine": {
        "type": "object",
        "properties": {
          "description": {
            "type": "string"
          },
          "amountPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "reference": {
            "type": "string",
            "description": "Legislation or HMRC manual reference."
          }
        },
        "required": [
          "description",
          "amountPence",
          "reference"
        ]
      },
      "SaSingleAssetPool": {
        "type": "object",
        "properties": {
          "assetId": {
            "type": "string"
          },
          "ref": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "businessUsePercent": {
            "type": "number"
          },
          "allowancePence": {
            "type": "integer",
            "description": "Allowance before the private-use restriction."
          },
          "aiaPence": {
            "type": "integer",
            "description": "Of the allowance before the restriction, the Annual Investment Allowance (CAA 2001 s51A)."
          },
          "claimedPence": {
            "type": "integer",
            "description": "Allowance claimed (business share)."
          }
        },
        "required": [
          "assetId",
          "ref",
          "description",
          "businessUsePercent",
          "allowancePence",
          "aiaPence",
          "claimedPence"
        ]
      },
      "SaCapitalAllowances": {
        "type": "object",
        "properties": {
          "fromRegister": {
            "type": "boolean"
          },
          "annualInvestmentAllowancePence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "firstYearAllowancesPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "mainPoolWdaPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "specialRatePoolWdaPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "singleAssetPoolsPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "structuresAndBuildingsPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "balancingAllowancesPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "totalPence": {
            "type": "integer",
            "description": "Allowances claimed, after the private-use restriction."
          },
          "balancingChargesPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "privateUseRestrictionPence": {
            "type": "integer",
            "description": "Allowances not given because of private use (CAA 2001 s207)."
          },
          "singleAssetPools": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SaSingleAssetPool"
            }
          },
          "mainPoolCfPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "specialRatePoolCfPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          }
        },
        "required": [
          "fromRegister",
          "annualInvestmentAllowancePence",
          "firstYearAllowancesPence",
          "mainPoolWdaPence",
          "specialRatePoolWdaPence",
          "singleAssetPoolsPence",
          "structuresAndBuildingsPence",
          "balancingAllowancesPence",
          "totalPence",
          "balancingChargesPence",
          "privateUseRestrictionPence",
          "singleAssetPools",
          "mainPoolCfPence",
          "specialRatePoolCfPence"
        ]
      },
      "TradingAllowanceClaimed": {
        "type": "string",
        "enum": [
          "none",
          "full-relief",
          "partial-relief"
        ]
      },
      "SaTaxYearShare": {
        "type": "object",
        "properties": {
          "taxYear": {
            "type": "integer"
          },
          "label": {
            "type": "string",
            "example": "2025/26"
          },
          "start": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "end": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "days": {
            "type": "integer"
          },
          "periodDays": {
            "type": "integer"
          },
          "sharePence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          }
        },
        "required": [
          "taxYear",
          "label",
          "start",
          "end",
          "days",
          "periodDays",
          "sharePence"
        ]
      },
      "SaPeriodSource": {
        "type": "string",
        "enum": [
          "this",
          "other",
          "provisional"
        ]
      },
      "SaApportionment": {
        "type": "object",
        "properties": {
          "start": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "end": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "source": {
            "allOf": [
              {
                "$ref": "#/components/schemas/SaPeriodSource"
              }
            ]
          },
          "days": {
            "type": "integer"
          },
          "daysInBasisPeriod": {
            "type": "integer"
          },
          "profitPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "sharePence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          }
        },
        "required": [
          "start",
          "end",
          "source",
          "days",
          "daysInBasisPeriod",
          "profitPence",
          "sharePence"
        ]
      },
      "SaSpreadYear": {
        "type": "object",
        "properties": {
          "taxYear": {
            "type": "integer"
          },
          "label": {
            "type": "string"
          },
          "amountPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          }
        },
        "required": [
          "taxYear",
          "label",
          "amountPence"
        ]
      },
      "SaTransition": {
        "type": "object",
        "properties": {
          "standardPart": {
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/SaDateRange"
              }
            ]
          },
          "standardPartProfitPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "transitionPart": {
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/SaDateRange"
              }
            ]
          },
          "transitionPartProfitPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "overlapReliefPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "excessOverlapReliefPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "transitionProfitPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "spread": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SaSpreadYear"
            }
          },
          "thisYearPence": {
            "type": "integer",
            "description": "Transition profit taxed in this tax year."
          }
        },
        "required": [
          "standardPart",
          "standardPartProfitPence",
          "transitionPart",
          "transitionPartProfitPence",
          "overlapReliefPence",
          "excessOverlapReliefPence",
          "transitionProfitPence",
          "spread",
          "thisYearPence"
        ]
      },
      "SaClass4": {
        "type": "object",
        "properties": {
          "taxYear": {
            "type": "integer"
          },
          "profits": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "mainRateBand": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "mainRateNic": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "additionalRateBand": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "additionalRateNic": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "total": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          }
        },
        "required": [
          "taxYear",
          "profits",
          "mainRateBand",
          "mainRateNic",
          "additionalRateBand",
          "additionalRateNic",
          "total"
        ]
      },
      "SaClass2Status": {
        "type": "string",
        "enum": [
          "payable",
          "treated-as-paid",
          "voluntary"
        ]
      },
      "SaClass2": {
        "type": "object",
        "properties": {
          "taxYear": {
            "type": "integer"
          },
          "status": {
            "allOf": [
              {
                "$ref": "#/components/schemas/SaClass2Status"
              }
            ]
          },
          "weeklyRate": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "payable": {
            "type": "integer",
            "description": "Compulsory Class 2 (nil from 2024/25)."
          },
          "voluntaryAnnualCost": {
            "type": "integer",
            "description": "Cost of a full year of voluntary contributions, where relevant."
          }
        },
        "required": [
          "taxYear",
          "status",
          "weeklyRate",
          "payable",
          "voluntaryAnnualCost"
        ]
      },
      "SaTaxYearWorking": {
        "type": "object",
        "properties": {
          "taxYear": {
            "type": "integer"
          },
          "label": {
            "type": "string"
          },
          "basisPeriod": {
            "$ref": "#/components/schemas/SaDateRange"
          },
          "apportionments": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SaApportionment"
            }
          },
          "basisPeriodProfitPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "transition": {
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/SaTransition"
              }
            ]
          },
          "lossesBroughtForwardUsedPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "taxableProfitPence": {
            "type": "integer",
            "description": "Whole pounds (floored), in pence."
          },
          "lossPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "lossCarriedForwardPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "class4": {
            "$ref": "#/components/schemas/SaClass4"
          },
          "class2": {
            "$ref": "#/components/schemas/SaClass2"
          }
        },
        "required": [
          "taxYear",
          "label",
          "basisPeriod",
          "apportionments",
          "basisPeriodProfitPence",
          "transition",
          "lossesBroughtForwardUsedPence",
          "taxableProfitPence",
          "lossPence",
          "lossCarriedForwardPence",
          "class4",
          "class2"
        ]
      },
      "SelfEmploymentPages": {
        "type": "string",
        "enum": [
          "short",
          "full"
        ],
        "description": "Short pages (SA103S) below the VAT registration threshold, else full (SA103F)."
      },
      "SaExpenseLine": {
        "type": "object",
        "properties": {
          "category": {
            "allOf": [
              {
                "$ref": "#/components/schemas/Sa103ExpenseCategory"
              }
            ]
          },
          "label": {
            "type": "string"
          },
          "totalPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "disallowablePence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          }
        },
        "required": [
          "category",
          "label",
          "totalPence",
          "disallowablePence"
        ]
      },
      "Sa103Figures": {
        "type": "object",
        "properties": {
          "pages": {
            "description": "Short pages (SA103S) below the VAT registration threshold, else full (SA103F).",
            "allOf": [
              {
                "$ref": "#/components/schemas/SelfEmploymentPages"
              }
            ]
          },
          "turnoverPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "otherBusinessIncomePence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "expenses": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SaExpenseLine"
            }
          },
          "totalExpensesPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "netProfitPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "goodsForOwnUsePence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "disallowableExpensesPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "balancingChargesPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "capitalAllowancesPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "tradingAllowanceClaimed": {
            "type": "boolean"
          },
          "adjustedProfitPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "basisPeriodAdjustmentPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "transitionProfitPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "lossesBroughtForwardUsedPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "taxableProfitPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "class4Pence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          }
        },
        "required": [
          "pages",
          "turnoverPence",
          "otherBusinessIncomePence",
          "expenses",
          "totalExpensesPence",
          "netProfitPence",
          "goodsForOwnUsePence",
          "disallowableExpensesPence",
          "balancingChargesPence",
          "capitalAllowancesPence",
          "tradingAllowanceClaimed",
          "adjustedProfitPence",
          "basisPeriodAdjustmentPence",
          "transitionProfitPence",
          "lossesBroughtForwardUsedPence",
          "taxableProfitPence",
          "class4Pence"
        ]
      },
      "SaSoleTrader": {
        "type": "object",
        "properties": {
          "working": {
            "description": "Null until every period needed for the return year has a figure.",
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/SaTaxYearWorking"
              }
            ]
          },
          "sa103": {
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/Sa103Figures"
              }
            ]
          }
        },
        "required": [
          "working",
          "sa103"
        ]
      },
      "SaSegmentPartner": {
        "type": "object",
        "properties": {
          "partnerId": {
            "type": "string"
          },
          "salaryPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "interestPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "residualSharePence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "totalPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          }
        },
        "required": [
          "partnerId",
          "salaryPence",
          "interestPence",
          "residualSharePence",
          "totalPence"
        ]
      },
      "SaSegment": {
        "type": "object",
        "properties": {
          "start": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "end": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "days": {
            "type": "integer"
          },
          "profitPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "partners": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SaSegmentPartner"
            }
          }
        },
        "required": [
          "start",
          "end",
          "days",
          "profitPence",
          "partners"
        ]
      },
      "SaPartnerResult": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "kind": {
            "allOf": [
              {
                "$ref": "#/components/schemas/SaPartnerKind"
              }
            ]
          },
          "joined": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31"
          },
          "left": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31"
          },
          "salaryPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "interestPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "residualSharePence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "notionalSharePence": {
            "type": "integer",
            "description": "Share before any reallocation of notional losses (ITTOIA 2005 s850A/s850B)."
          },
          "sharePence": {
            "type": "integer",
            "description": "Share of the tax-adjusted profit: the partnership statement figure."
          },
          "accountingSharePence": {
            "type": "integer",
            "description": "Share of the accounting profit per the arrangement."
          },
          "taxYears": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SaTaxYearShare"
            }
          },
          "working": {
            "description": "Individuals only.",
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/SaTaxYearWorking"
              }
            ]
          },
          "missingPeriods": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SaDateRange"
            }
          },
          "error": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "id",
          "name",
          "kind",
          "joined",
          "left",
          "salaryPence",
          "interestPence",
          "residualSharePence",
          "notionalSharePence",
          "sharePence",
          "accountingSharePence",
          "taxYears",
          "working",
          "missingPeriods",
          "error"
        ]
      },
      "Sa800Figures": {
        "type": "object",
        "properties": {
          "turnoverPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "accountingProfitPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "taxAdjustedProfitPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "sharesAgree": {
            "type": "boolean"
          }
        },
        "required": [
          "turnoverPence",
          "accountingProfitPence",
          "taxAdjustedProfitPence",
          "sharesAgree"
        ]
      },
      "SaPartnership": {
        "type": "object",
        "properties": {
          "segments": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SaSegment"
            }
          },
          "partners": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SaPartnerResult"
            }
          },
          "reallocated": {
            "type": "boolean"
          },
          "unallocatedPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "sa800": {
            "$ref": "#/components/schemas/Sa800Figures"
          }
        },
        "required": [
          "segments",
          "partners",
          "reallocated",
          "unallocatedPence",
          "sa800"
        ]
      },
      "SaPrivateUseAsset": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "ref": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "ref"
        ]
      },
      "SaPrivateUseUnrecorded": {
        "type": "object",
        "properties": {
          "accounts": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "assets": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SaPrivateUseAsset"
            }
          }
        },
        "required": [
          "accounts",
          "assets"
        ]
      },
      "SaSummary": {
        "type": "object",
        "properties": {
          "label": {
            "type": "string",
            "example": "Taxable profit 2025/26"
          },
          "valuePence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "detail": {
            "type": "string"
          }
        },
        "required": [
          "label",
          "valuePence",
          "detail"
        ]
      },
      "SelfAssessmentComputation": {
        "type": "object",
        "properties": {
          "entity": {
            "allOf": [
              {
                "$ref": "#/components/schemas/SaEntity"
              }
            ]
          },
          "error": {
            "type": [
              "string",
              "null"
            ]
          },
          "warnings": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "inputs": {
            "$ref": "#/components/schemas/SelfAssessmentInputs"
          },
          "period": {
            "$ref": "#/components/schemas/SaDateRange"
          },
          "accounts": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SaAccountRow"
            }
          },
          "profitPerAccountsPence": {
            "type": "integer",
            "description": "Net profit per the final TB."
          },
          "turnoverPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "interestReceivedPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "adjustments": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SaLine"
            }
          },
          "capitalAllowances": {
            "$ref": "#/components/schemas/SaCapitalAllowances"
          },
          "adjustedProfitActualPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "tradingAllowanceClaimed": {
            "allOf": [
              {
                "$ref": "#/components/schemas/TradingAllowanceClaimed"
              }
            ]
          },
          "adjustedProfitPence": {
            "type": "integer",
            "description": "Tax-adjusted trading profit of the period (after capital allowances and any trading allowance)."
          },
          "taxYears": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SaTaxYearShare"
            }
          },
          "returnTaxYear": {
            "type": "integer"
          },
          "returnTaxYearLabel": {
            "type": "string"
          },
          "missingPeriods": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SaDateRange"
            }
          },
          "soleTrader": {
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/SaSoleTrader"
              }
            ]
          },
          "partnership": {
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/SaPartnership"
              }
            ]
          },
          "privateUseUnrecorded": {
            "$ref": "#/components/schemas/SaPrivateUseUnrecorded"
          },
          "drawingsPence": {
            "type": "integer",
            "description": "Drawings per the final TB (debit positive)."
          },
          "allocatedToMembersPerTbPence": {
            "type": "integer",
            "description": "LLP: profit allocated to members per the final TB (debit positive)."
          },
          "summary": {
            "description": "The overview stat: the taxable profit (sole traders) or the amount allocated to partners or members.",
            "allOf": [
              {
                "$ref": "#/components/schemas/SaSummary"
              }
            ]
          },
          "lockedReason": {
            "type": [
              "string",
              "null"
            ],
            "description": "Why a preparer cannot change the inputs now (section T reviewed)."
          },
          "inputsSetUp": {
            "type": "boolean",
            "description": "The preparer has saved the inputs (PUT …/self-assessment/inputs) at least once, so the computation is set up."
          }
        },
        "required": [
          "entity",
          "error",
          "warnings",
          "inputs",
          "period",
          "accounts",
          "profitPerAccountsPence",
          "turnoverPence",
          "interestReceivedPence",
          "adjustments",
          "capitalAllowances",
          "adjustedProfitActualPence",
          "tradingAllowanceClaimed",
          "adjustedProfitPence",
          "taxYears",
          "returnTaxYear",
          "returnTaxYearLabel",
          "missingPeriods",
          "soleTrader",
          "partnership",
          "privateUseUnrecorded",
          "drawingsPence",
          "allocatedToMembersPerTbPence",
          "summary",
          "lockedReason"
        ]
      },
      "SetSelfAssessmentInputs": {
        "type": "object",
        "properties": {
          "accounts": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SaAccountTreatment"
            }
          },
          "goodsForOwnUsePence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "otherAdjustments": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SaAdjustmentInput"
            }
          },
          "tradingAllowance": {
            "allOf": [
              {
                "$ref": "#/components/schemas/TradingAllowanceChoice"
              }
            ]
          },
          "lateAccountingDates": {
            "type": "boolean"
          },
          "commencementDate": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31"
          },
          "cessationDate": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31"
          },
          "otherPeriods": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SaOtherPeriod"
            }
          },
          "overlapReliefPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "transitionProfitPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "lossesBroughtForwardPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "partners": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SaPartner"
            }
          },
          "arrangements": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SaArrangement"
            }
          }
        }
      },
      "RaiseReviewPoint": {
        "type": "object",
        "properties": {
          "sectionCode": {
            "type": [
              "string",
              "null"
            ],
            "description": "Section code; omit or null for the engagement as a whole."
          },
          "category": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ReviewPointCategory"
              }
            ]
          },
          "body": {
            "type": "string",
            "minLength": 1,
            "maxLength": 4000,
            "description": "@Full Name mentions are recognised."
          },
          "mentions": {
            "maxItems": 50,
            "description": "People to mention, in addition to @names in the text.",
            "type": "array",
            "items": {
              "type": "string",
              "format": "uuid"
            }
          }
        },
        "required": [
          "category",
          "body"
        ]
      },
      "ReviewPointReply": {
        "type": "object",
        "properties": {
          "body": {
            "type": "string",
            "maxLength": 4000
          },
          "mentions": {
            "maxItems": 50,
            "type": "array",
            "items": {
              "type": "string",
              "format": "uuid"
            }
          },
          "evidenceIds": {
            "maxItems": 20,
            "description": "Evidence uploaded for this review point, attached to the reply.",
            "type": "array",
            "items": {
              "type": "string",
              "format": "uuid"
            }
          }
        }
      },
      "ReviewPointAction": {
        "type": "object",
        "properties": {
          "body": {
            "type": "string",
            "maxLength": 4000,
            "description": "Required to reopen."
          }
        }
      },
      "ApprovalDeclaration": {
        "type": "object",
        "properties": {
          "initials": {
            "type": "string",
            "minLength": 1,
            "maxLength": 10,
            "description": "The approver’s initials, typed as a signature."
          },
          "statement": {
            "type": "string",
            "minLength": 1,
            "maxLength": 500,
            "description": "What they declared, e.g. \"I have reviewed the file and approve the accounts for issue to the client.\""
          }
        },
        "description": "The approver’s declaration, recorded with the approval in the audit trail.",
        "required": [
          "initials",
          "statement"
        ]
      },
      "WorkflowEvent": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "subject": {
            "type": "string",
            "description": "\"engagement\" or a section code."
          },
          "type": {
            "type": "string"
          },
          "stageId": {
            "type": "string"
          },
          "actorId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "at": {
            "type": "string",
            "format": "date-time"
          },
          "fromStatus": {
            "type": "string"
          },
          "toStatus": {
            "type": "string"
          },
          "round": {
            "type": "integer"
          },
          "openPoints": {
            "type": "integer"
          },
          "fingerprint": {
            "type": [
              "string",
              "null"
            ]
          },
          "note": {
            "type": [
              "string",
              "null"
            ],
            "description": "The note given with a submission or approval."
          },
          "declaration": {
            "description": "The declaration given with an approval.",
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/ApprovalDeclaration"
              }
            ]
          }
        },
        "required": [
          "id",
          "subject",
          "type",
          "stageId",
          "actorId",
          "at",
          "fromStatus",
          "toStatus",
          "round",
          "openPoints",
          "fingerprint"
        ]
      },
      "WorkflowHistory": {
        "type": "object",
        "properties": {
          "workflow": {
            "$ref": "#/components/schemas/EngagementWorkflow"
          },
          "events": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/WorkflowEvent"
            }
          }
        },
        "required": [
          "workflow",
          "events"
        ]
      },
      "SubmitEngagement": {
        "type": "object",
        "properties": {
          "reviewerId": {
            "type": "string",
            "format": "uuid",
            "description": "The person for the next stage (reviewer, manager or partner by the stage’s role). Saved on the engagement team, replacing whoever was there, and told about the submission. Must be a member of the firm."
          },
          "note": {
            "type": "string",
            "maxLength": 2000,
            "description": "A cover note for the reviewer: kept with the submission in the history and sent with the notification."
          }
        },
        "description": "Optional: name who reviews next and leave them a note."
      },
      "ApproveEngagement": {
        "type": "object",
        "properties": {
          "reviewerId": {
            "type": "string",
            "format": "uuid",
            "description": "The person for the next stage (manager or partner by the stage’s role), as on submit. Saved on the engagement team, replacing whoever was there, and told about the approval. Must be a member of the firm. Ignored at the last stage."
          },
          "note": {
            "type": "string",
            "maxLength": 2000,
            "description": "A note kept with the approval in the history and sent with the notification."
          },
          "declaration": {
            "description": "The approver’s declaration with their typed initials (the web app asks for one at partner sign-off).",
            "allOf": [
              {
                "$ref": "#/components/schemas/ApprovalDeclaration"
              }
            ]
          }
        }
      },
      "ReturnEngagement": {
        "type": "object",
        "properties": {
          "toStageId": {
            "type": "string",
            "description": "Default: the first stage."
          },
          "reviewPointIds": {
            "description": "Default: every unanswered review point.",
            "type": "array",
            "items": {
              "type": "string",
              "format": "uuid"
            }
          },
          "note": {
            "type": "string",
            "maxLength": 2000,
            "description": "A note for the preparer: kept with the return in the history and sent with the notification."
          }
        }
      },
      "ReopenEngagement": {
        "type": "object",
        "properties": {
          "toStageId": {
            "type": "string",
            "description": "Default: the first review stage."
          }
        }
      },
      "NotificationType": {
        "type": "string",
        "enum": [
          "mention",
          "rp",
          "cleared",
          "review",
          "sync",
          "assign",
          "deadline",
          "filing",
          "billing",
          "ai_tokens",
          "evidence"
        ]
      },
      "NotificationProduct": {
        "type": "string",
        "enum": [
          "working_papers",
          "meetings",
          "suite",
          "self_assessment",
          "accounts",
          "corporation_tax"
        ],
        "description": "The product it came from; suite for firm-wide notices such as billing and AI tokens."
      },
      "Notification": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "type": {
            "allOf": [
              {
                "$ref": "#/components/schemas/NotificationType"
              }
            ]
          },
          "text": {
            "type": "string"
          },
          "engagementId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "sectionCode": {
            "type": [
              "string",
              "null"
            ]
          },
          "reviewPointId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "actorId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "actorName": {
            "type": [
              "string",
              "null"
            ],
            "description": "Who did it, by name; null for Tolvi itself (deadlines, syncs, billing)."
          },
          "product": {
            "description": "The product it came from; suite for firm-wide notices such as billing and AI tokens.",
            "allOf": [
              {
                "$ref": "#/components/schemas/NotificationProduct"
              }
            ]
          },
          "subjectId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid",
            "description": "The return or set of accounts it is about, for those products."
          },
          "email": {
            "type": "boolean"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "readAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "type",
          "text",
          "engagementId",
          "sectionCode",
          "reviewPointId",
          "actorId",
          "email",
          "createdAt",
          "readAt"
        ]
      },
      "NotificationPage": {
        "type": "object",
        "properties": {
          "rows": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Notification"
            }
          },
          "unread": {
            "type": "integer"
          }
        },
        "required": [
          "rows",
          "unread"
        ]
      },
      "MappingRuleKind": {
        "type": "string",
        "enum": [
          "name",
          "code_range"
        ]
      },
      "MappingRule": {
        "type": "object",
        "properties": {
          "kind": {
            "allOf": [
              {
                "$ref": "#/components/schemas/MappingRuleKind"
              }
            ]
          },
          "pattern": {
            "type": "string",
            "maxLength": 200,
            "description": "A name pattern (case-insensitive wildcards: * any characters, ? one character, | alternatives, ^ start, $ end; not a regular expression) or a code range \"4000-4899\"."
          },
          "lineId": {
            "allOf": [
              {
                "$ref": "#/components/schemas/LeadLineId"
              }
            ]
          }
        },
        "required": [
          "kind",
          "pattern",
          "lineId"
        ]
      },
      "MappingRules": {
        "type": "object",
        "properties": {
          "rules": {
            "maxItems": 500,
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/MappingRule"
            }
          }
        },
        "required": [
          "rules"
        ]
      },
      "ChecklistTemplate": {
        "type": "object",
        "properties": {
          "sectionCode": {
            "type": "string"
          },
          "items": {
            "maxItems": 100,
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "builtin": {
            "type": "boolean",
            "description": "Tolvi’s built-in wording (the firm has not set its own)."
          }
        },
        "description": "The firm’s steps for one section; an empty list restores the built-in steps.",
        "required": [
          "sectionCode",
          "items",
          "builtin"
        ]
      },
      "SetChecklistTemplate": {
        "type": "object",
        "properties": {
          "items": {
            "maxItems": 100,
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        },
        "required": [
          "items"
        ]
      },
      "ClientChecklistStep": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "sectionCode": {
            "type": "string"
          },
          "text": {
            "type": "string"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "sectionCode",
          "text",
          "createdAt"
        ]
      },
      "CreateClientChecklistStep": {
        "type": "object",
        "properties": {
          "sectionCode": {
            "type": "string"
          },
          "text": {
            "type": "string",
            "minLength": 1,
            "maxLength": 500
          }
        },
        "required": [
          "sectionCode",
          "text"
        ]
      },
      "FirmDetails": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "maxLength": 200
          },
          "tagline": {
            "type": "string",
            "maxLength": 200
          },
          "offices": {
            "maxItems": 50,
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        }
      },
      "FirmThresholds": {
        "type": "object",
        "properties": {
          "absolutePence": {
            "type": "integer",
            "description": "Integer pence (GBP).",
            "minimum": 0
          },
          "percent": {
            "type": "integer",
            "minimum": 0,
            "maximum": 1000
          }
        },
        "description": "Movements at or above both thresholds need an explanation. New engagements copy these.",
        "required": [
          "absolutePence",
          "percent"
        ]
      },
      "ApprovalSettings": {
        "type": "object",
        "properties": {
          "approverRole": {
            "description": "The lowest role that may approve: partners only, or managers and partners.",
            "allOf": [
              {
                "$ref": "#/components/schemas/ApproverRole"
              }
            ]
          }
        },
        "description": "Who approves accounts and returns in Accounts, Corporation Tax and Self Assessment.",
        "required": [
          "approverRole"
        ]
      },
      "DefaultWorkflows": {
        "type": "object",
        "properties": {
          "LTD_FRS102_1A": {
            "type": "string"
          },
          "LTD_FRS105_MICRO": {
            "type": "string"
          },
          "LLP": {
            "type": "string"
          },
          "SOLE_TRADER": {
            "type": "string"
          },
          "PARTNERSHIP": {
            "type": "string"
          },
          "INDIVIDUAL": {
            "type": "string"
          },
          "TRUST": {
            "type": "string"
          },
          "ESTATE": {
            "type": "string"
          },
          "CHARITY_UNINCORPORATED": {
            "type": "string"
          },
          "CHARITY_TRUST": {
            "type": "string"
          },
          "CIO": {
            "type": "string"
          },
          "SCIO": {
            "type": "string"
          },
          "CHARITABLE_COMPANY": {
            "type": "string"
          }
        },
        "description": "Workflow template id (a preset or the firm’s own) by entity type.",
        "required": [
          "LTD_FRS102_1A",
          "LTD_FRS105_MICRO",
          "LLP",
          "SOLE_TRADER",
          "PARTNERSHIP",
          "TRUST",
          "ESTATE",
          "CHARITY_UNINCORPORATED",
          "CHARITY_TRUST",
          "CIO",
          "SCIO",
          "CHARITABLE_COMPANY"
        ]
      },
      "NotificationChannels": {
        "type": "object",
        "properties": {
          "app": {
            "type": "boolean"
          },
          "email": {
            "type": "boolean"
          },
          "digest": {
            "type": "boolean"
          }
        },
        "required": [
          "app",
          "email",
          "digest"
        ]
      },
      "NotificationPrefs": {
        "type": "object",
        "properties": {
          "mention": {
            "$ref": "#/components/schemas/NotificationChannels"
          },
          "rp": {
            "$ref": "#/components/schemas/NotificationChannels"
          },
          "cleared": {
            "$ref": "#/components/schemas/NotificationChannels"
          },
          "review": {
            "$ref": "#/components/schemas/NotificationChannels"
          },
          "sync": {
            "$ref": "#/components/schemas/NotificationChannels"
          },
          "assign": {
            "$ref": "#/components/schemas/NotificationChannels"
          },
          "deadline": {
            "$ref": "#/components/schemas/NotificationChannels"
          },
          "filing": {
            "description": "HMRC’s reply to a return.",
            "allOf": [
              {
                "$ref": "#/components/schemas/NotificationChannels"
              }
            ]
          }
        },
        "description": "Channels per notification type. Mentions and assignments are always in-app.",
        "required": [
          "mention",
          "rp",
          "cleared",
          "review",
          "sync",
          "assign",
          "deadline"
        ]
      },
      "SyncFrequency": {
        "type": "string",
        "enum": [
          "nightly",
          "weekly"
        ]
      },
      "SyncOnChange": {
        "type": "string",
        "enum": [
          "notify",
          "reopen",
          "none"
        ]
      },
      "SyncDigest": {
        "type": "string",
        "enum": [
          "daily",
          "instant",
          "off"
        ]
      },
      "SyncSettings": {
        "type": "object",
        "properties": {
          "frequency": {
            "allOf": [
              {
                "$ref": "#/components/schemas/SyncFrequency"
              }
            ]
          },
          "time": {
            "type": "string",
            "pattern": "^([01]\\d|2[0-3]):[0-5]\\d$",
            "example": "02:00"
          },
          "ignoreUnderPence": {
            "type": "integer",
            "description": "Integer pence (GBP).",
            "minimum": 0
          },
          "comparePriorYear": {
            "type": "boolean"
          },
          "onChange": {
            "allOf": [
              {
                "$ref": "#/components/schemas/SyncOnChange"
              }
            ]
          },
          "digest": {
            "allOf": [
              {
                "$ref": "#/components/schemas/SyncDigest"
              }
            ]
          }
        },
        "required": [
          "frequency",
          "time",
          "ignoreUnderPence",
          "comparePriorYear",
          "onChange",
          "digest"
        ]
      },
      "EmailSettings": {
        "type": "object",
        "properties": {
          "timeZone": {
            "type": "string",
            "maxLength": 64,
            "description": "IANA time zone, e.g. Europe/London."
          },
          "digestHour": {
            "type": "integer",
            "minimum": 0,
            "maximum": 23,
            "description": "Local hour (0–23) from which the digest and reminders are sent."
          }
        },
        "description": "When the daily digest and deadline reminders go out, in the firm’s local time.",
        "required": [
          "timeZone",
          "digestHour"
        ]
      },
      "SecuritySettings": {
        "type": "object",
        "properties": {
          "mfa": {
            "type": "boolean",
            "description": "Enforced: sign-in tokens must show a second factor (amr / acr)."
          },
          "sso": {
            "type": "boolean"
          },
          "timeoutMinutes": {
            "type": "integer",
            "minimum": 5,
            "maximum": 1440,
            "description": "Enforced: people sign in again this long after they last signed in (auth_time)."
          },
          "retentionYears": {
            "type": "integer",
            "minimum": 6,
            "maximum": 20,
            "description": "Not yet enforced: no deletion job runs yet, so records are currently kept indefinitely."
          }
        },
        "required": [
          "mfa",
          "sso",
          "timeoutMinutes",
          "retentionYears"
        ]
      },
      "Capacity": {
        "type": "object",
        "properties": {
          "preparer": {
            "type": [
              "integer",
              "null"
            ]
          },
          "reviewer": {
            "type": [
              "integer",
              "null"
            ]
          },
          "manager": {
            "type": [
              "integer",
              "null"
            ]
          },
          "partner": {
            "type": [
              "integer",
              "null"
            ]
          }
        },
        "description": "Open engagements a person can hold, by role (null: no limit).",
        "required": [
          "preparer",
          "reviewer",
          "manager",
          "partner"
        ]
      },
      "AiFeatureSwitches": {
        "type": "object",
        "properties": {
          "explain_movements": {
            "type": "boolean"
          },
          "suggest_mappings": {
            "type": "boolean"
          },
          "review_assistant": {
            "type": "boolean"
          },
          "check_evidence": {
            "type": "boolean"
          },
          "explain_sync_changes": {
            "type": "boolean"
          },
          "ask_tolvi": {
            "type": "boolean"
          },
          "draft_client_queries": {
            "type": "boolean"
          },
          "summarise_meeting": {
            "type": "boolean",
            "description": "Meetings: summary and actions after each recorded meeting. Optional when saving (unchanged if left out)."
          },
          "sa_assistant": {
            "type": "boolean",
            "description": "Self Assessment: AI Mode. Optional when saving (unchanged if left out)."
          },
          "sa_read_document": {
            "type": "boolean",
            "description": "Self Assessment: reading uploaded documents in AI Mode. Optional when saving (unchanged if left out)."
          },
          "accounts_draft_note": {
            "type": "boolean",
            "description": "Accounts: drafting note wording for a person to check. Optional when saving (unchanged if left out)."
          }
        },
        "required": [
          "explain_movements",
          "suggest_mappings",
          "review_assistant",
          "check_evidence",
          "explain_sync_changes",
          "ask_tolvi",
          "draft_client_queries"
        ]
      },
      "TokenBuyers": {
        "type": "string",
        "enum": [
          "partners_and_admins",
          "admins"
        ]
      },
      "TokenPackId": {
        "type": "string",
        "enum": [
          "starter",
          "practice",
          "firm"
        ]
      },
      "AutoTopUp": {
        "type": "object",
        "properties": {
          "enabled": {
            "type": "boolean"
          },
          "belowTokens": {
            "type": "integer",
            "minimum": 0
          },
          "packId": {
            "allOf": [
              {
                "$ref": "#/components/schemas/TokenPackId"
              }
            ]
          }
        },
        "required": [
          "enabled",
          "belowTokens",
          "packId"
        ]
      },
      "AiSettings": {
        "type": "object",
        "properties": {
          "enabled": {
            "type": "boolean"
          },
          "features": {
            "$ref": "#/components/schemas/AiFeatureSwitches"
          },
          "defaultMonthlyLimit": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 0,
            "description": "Tolvi AI tokens per person per UK calendar month; null for no limit."
          },
          "userLimits": {
            "type": "object",
            "additionalProperties": {
              "oneOf": [
                {
                  "type": "integer"
                },
                {
                  "type": "null"
                }
              ]
            },
            "description": "Per-person limits by user id (null: no limit)."
          },
          "buyers": {
            "allOf": [
              {
                "$ref": "#/components/schemas/TokenBuyers"
              }
            ]
          },
          "autoTopUp": {
            "$ref": "#/components/schemas/AutoTopUp"
          }
        },
        "description": "Tolvi AI controls: on/off, per-feature switches, monthly limits and who can buy tokens.",
        "required": [
          "enabled",
          "features",
          "defaultMonthlyLimit",
          "userLimits",
          "buyers",
          "autoTopUp"
        ]
      },
      "WorkflowStageRole": {
        "type": "string",
        "enum": [
          "preparer",
          "reviewer",
          "manager",
          "partner"
        ]
      },
      "StageScope": {
        "type": "string",
        "enum": [
          "section",
          "engagement",
          "both"
        ],
        "description": "Default both."
      },
      "WorkflowTemplateStage": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Stage id (read only)."
          },
          "name": {
            "type": "string",
            "maxLength": 100
          },
          "role": {
            "allOf": [
              {
                "$ref": "#/components/schemas/WorkflowStageRole"
              }
            ]
          },
          "mustDiffer": {
            "type": "boolean",
            "description": "Must be a different person from every earlier stage."
          },
          "scope": {
            "description": "Default both.",
            "allOf": [
              {
                "$ref": "#/components/schemas/StageScope"
              }
            ]
          }
        },
        "required": [
          "name",
          "role",
          "mustDiffer"
        ]
      },
      "WorkflowTemplate": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "A preset id (preset-…) or the firm template’s uuid."
          },
          "name": {
            "type": "string"
          },
          "builtin": {
            "type": "boolean",
            "description": "A Tolvi preset (read only)."
          },
          "version": {
            "type": "integer"
          },
          "stages": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/WorkflowTemplateStage"
            }
          }
        },
        "required": [
          "id",
          "name",
          "builtin",
          "version",
          "stages"
        ]
      },
      "FirmSettings": {
        "type": "object",
        "properties": {
          "firmName": {
            "type": "string"
          },
          "onboarded": {
            "type": "boolean"
          },
          "onboardedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "firm": {
            "$ref": "#/components/schemas/FirmDetails"
          },
          "thresholds": {
            "$ref": "#/components/schemas/FirmThresholds"
          },
          "approvals": {
            "$ref": "#/components/schemas/ApprovalSettings"
          },
          "reminderDays": {
            "type": "array",
            "items": {
              "type": "integer"
            }
          },
          "defaultWorkflows": {
            "$ref": "#/components/schemas/DefaultWorkflows"
          },
          "notifications": {
            "$ref": "#/components/schemas/NotificationPrefs"
          },
          "sync": {
            "$ref": "#/components/schemas/SyncSettings"
          },
          "email": {
            "$ref": "#/components/schemas/EmailSettings"
          },
          "security": {
            "$ref": "#/components/schemas/SecuritySettings"
          },
          "capacity": {
            "$ref": "#/components/schemas/Capacity"
          },
          "ai": {
            "$ref": "#/components/schemas/AiSettings"
          },
          "workflows": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/WorkflowTemplate"
            }
          }
        },
        "required": [
          "firmName",
          "onboarded",
          "onboardedAt",
          "firm",
          "thresholds",
          "approvals",
          "reminderDays",
          "defaultWorkflows",
          "notifications",
          "sync",
          "email",
          "security",
          "capacity",
          "ai",
          "workflows"
        ]
      },
      "Reminders": {
        "type": "object",
        "properties": {
          "reminderDays": {
            "maxItems": 10,
            "description": "Days before the filing deadline to remind whoever’s turn it is.",
            "type": "array",
            "items": {
              "type": "integer"
            }
          }
        },
        "required": [
          "reminderDays"
        ]
      },
      "OnboardingSteps": {
        "type": "object",
        "properties": {
          "firmDetails": {
            "type": "boolean"
          },
          "thresholds": {
            "type": "boolean"
          },
          "workflow": {
            "type": "boolean"
          },
          "team": {
            "type": "boolean",
            "description": "Someone else has joined."
          },
          "clients": {
            "type": "boolean",
            "description": "At least one client."
          },
          "colleagueInvited": {
            "type": "boolean",
            "description": "Someone else has joined, or has been invited (and the invitation not withdrawn)."
          },
          "bookkeepingConnected": {
            "type": "boolean",
            "description": "At least one client is connected to its bookkeeping software (Xero, QuickBooks, Sage or FreeAgent)."
          },
          "engagementStarted": {
            "type": "boolean",
            "description": "At least one engagement has been started."
          }
        },
        "required": [
          "firmDetails",
          "thresholds",
          "workflow",
          "team",
          "clients",
          "colleagueInvited",
          "bookkeepingConnected",
          "engagementStarted"
        ]
      },
      "OnboardingStatus": {
        "type": "object",
        "properties": {
          "onboarded": {
            "type": "boolean"
          },
          "onboardedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "steps": {
            "$ref": "#/components/schemas/OnboardingSteps"
          }
        },
        "required": [
          "onboarded",
          "onboardedAt",
          "steps"
        ]
      },
      "OnboardingAction": {
        "type": "string",
        "enum": [
          "complete",
          "skip"
        ]
      },
      "CompleteOnboarding": {
        "type": "object",
        "properties": {
          "action": {
            "allOf": [
              {
                "$ref": "#/components/schemas/OnboardingAction"
              }
            ]
          },
          "firmName": {
            "type": "string",
            "maxLength": 200
          },
          "offices": {
            "maxItems": 50,
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "thresholds": {
            "$ref": "#/components/schemas/FirmThresholds"
          },
          "defaultWorkflowId": {
            "type": "string",
            "description": "Becomes the default workflow for every entity type."
          }
        },
        "required": [
          "action"
        ]
      },
      "OnboardingStep": {
        "type": "string",
        "enum": [
          "firm",
          "clients",
          "team",
          "review",
          "finish"
        ],
        "description": "The step to resume at."
      },
      "OnboardingClientSource": {
        "type": "string",
        "enum": [
          "xero",
          "csv",
          "one",
          "later"
        ],
        "description": "How clients are being brought in; null until chosen."
      },
      "QueuedInvitation": {
        "type": "object",
        "properties": {
          "email": {
            "type": "string",
            "format": "email",
            "maxLength": 254
          },
          "staffRole": {
            "allOf": [
              {
                "$ref": "#/components/schemas/StaffRole"
              }
            ]
          }
        },
        "description": "Someone to invite when first-run setup finishes. Nothing is sent until then.",
        "required": [
          "email",
          "staffRole"
        ]
      },
      "OnboardingProgress": {
        "type": "object",
        "properties": {
          "step": {
            "description": "The step to resume at.",
            "allOf": [
              {
                "$ref": "#/components/schemas/OnboardingStep"
              }
            ]
          },
          "clientSource": {
            "description": "How clients are being brought in; null until chosen.",
            "oneOf": [
              {
                "$ref": "#/components/schemas/OnboardingClientSource"
              },
              {
                "type": "null"
              }
            ]
          },
          "invitations": {
            "maxItems": 50,
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/QueuedInvitation"
            }
          },
          "updatedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "When it was last saved; null when nothing has been saved yet."
          }
        },
        "description": "First-run setup saved as it goes, so it resumes where it was left. Firm details, thresholds and workflows are saved to the settings themselves; this keeps the step reached, how clients are being brought in, and the invitations queued to send on the last step.",
        "required": [
          "step",
          "clientSource",
          "invitations",
          "updatedAt"
        ]
      },
      "SaveOnboardingProgress": {
        "type": "object",
        "properties": {
          "step": {
            "allOf": [
              {
                "$ref": "#/components/schemas/OnboardingStep"
              }
            ]
          },
          "clientSource": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/OnboardingClientSource"
              },
              {
                "type": "null"
              }
            ]
          },
          "invitations": {
            "maxItems": 50,
            "description": "Replaces the queued invitations when given.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/QueuedInvitation"
            }
          }
        },
        "required": [
          "step"
        ]
      },
      "WorkflowTemplateInput": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "Keep to update an existing template."
          },
          "name": {
            "type": "string",
            "maxLength": 100
          },
          "stages": {
            "minItems": 1,
            "maxItems": 8,
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/WorkflowTemplateStage"
            }
          }
        },
        "required": [
          "name",
          "stages"
        ]
      },
      "SetWorkflowTemplates": {
        "type": "object",
        "properties": {
          "templates": {
            "maxItems": 20,
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/WorkflowTemplateInput"
            }
          }
        },
        "description": "The firm’s templates (presets are always available). Templates left out are archived.",
        "required": [
          "templates"
        ]
      },
      "OpenByRole": {
        "type": "object",
        "properties": {
          "preparer": {
            "type": "integer"
          },
          "reviewer": {
            "type": "integer"
          },
          "manager": {
            "type": "integer"
          },
          "partner": {
            "type": "integer"
          }
        },
        "description": "Open engagements a person is on, by their role on each.",
        "required": [
          "preparer",
          "reviewer",
          "manager",
          "partner"
        ]
      },
      "Member": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "email": {
            "type": "string"
          },
          "initials": {
            "type": "string"
          },
          "role": {
            "allOf": [
              {
                "$ref": "#/components/schemas/MembershipRole"
              }
            ]
          },
          "staffRole": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/StaffRole"
              },
              {
                "type": "null"
              }
            ]
          },
          "isAdmin": {
            "type": "boolean"
          },
          "capacity": {
            "type": [
              "integer",
              "null"
            ]
          },
          "openEngagements": {
            "type": "integer",
            "description": "Open engagements where it is their turn."
          },
          "openOnTeam": {
            "type": "integer",
            "description": "Open engagements they are on in any role (preparer, reviewer, manager or partner), each counted once."
          },
          "openByRole": {
            "description": "Open engagements they are on, by role.",
            "allOf": [
              {
                "$ref": "#/components/schemas/OpenByRole"
              }
            ]
          },
          "joinedAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "name",
          "email",
          "initials",
          "role",
          "staffRole",
          "isAdmin",
          "capacity",
          "openEngagements",
          "joinedAt"
        ]
      },
      "ClientOverrides": {
        "type": "object",
        "properties": {
          "risk": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/RiskLevel"
              },
              {
                "type": "null"
              }
            ]
          },
          "workflowTemplateId": {
            "type": [
              "string",
              "null"
            ]
          },
          "thresholdAbsPence": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Integer pence (GBP)."
          },
          "thresholdPct": {
            "type": [
              "integer",
              "null"
            ]
          },
          "materialityPence": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Integer pence (GBP)."
          },
          "deadlineOverride": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31",
            "description": "e.g. an extension or a changed accounting reference date."
          },
          "syncIgnoreUnderPence": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Integer pence (GBP)."
          },
          "syncExcludeCodes": {
            "maxItems": 200,
            "description": "Account codes the sign-off check leaves out for this client. Always present in responses.",
            "type": [
              "array",
              "null"
            ],
            "items": {
              "type": "string"
            }
          },
          "syncOnChange": {
            "description": "What the sign-off check does when this client’s books change. Always present in responses.",
            "oneOf": [
              {
                "$ref": "#/components/schemas/SyncOnChange"
              },
              {
                "type": "null"
              }
            ]
          }
        },
        "description": "A client’s settings that differ from the firm’s (null: use the firm default).",
        "required": [
          "risk",
          "workflowTemplateId",
          "thresholdAbsPence",
          "thresholdPct",
          "materialityPence",
          "deadlineOverride",
          "syncIgnoreUnderPence"
        ]
      },
      "ClientStepRef": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "sectionCode": {
            "type": "string"
          },
          "text": {
            "type": "string"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "sectionCode",
          "text",
          "createdAt"
        ]
      },
      "ClientEngagement": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "periodStart": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "periodEnd": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "dueDate": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "status": {
            "allOf": [
              {
                "$ref": "#/components/schemas/EngagementStatus"
              }
            ]
          },
          "stageName": {
            "type": "string"
          },
          "filedOn": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31"
          },
          "preparerId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "reviewerId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "rounds": {
            "type": "integer",
            "minimum": 0,
            "description": "Times sent back by a reviewer (amendment rounds)."
          },
          "openReviewPoints": {
            "type": "integer",
            "minimum": 0
          }
        },
        "required": [
          "id",
          "periodStart",
          "periodEnd",
          "dueDate",
          "status",
          "stageName",
          "filedOn",
          "preparerId",
          "reviewerId",
          "rounds",
          "openReviewPoints"
        ]
      },
      "ClientDetail": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "firmId": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "entityType": {
            "allOf": [
              {
                "$ref": "#/components/schemas/EntityType"
              }
            ]
          },
          "companyNumber": {
            "type": [
              "string",
              "null"
            ]
          },
          "yearEndDay": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 1,
            "maximum": 31,
            "description": "Financial year end day; null when not known."
          },
          "yearEndMonth": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 1,
            "maximum": 12
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "partnerId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid",
            "description": "From the latest engagement."
          },
          "managerId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "preparerId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid",
            "description": "From the latest engagement."
          },
          "reviewerId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid",
            "description": "From the latest engagement."
          },
          "software": {
            "allOf": [
              {
                "$ref": "#/components/schemas/Software"
              }
            ]
          },
          "syncState": {
            "allOf": [
              {
                "$ref": "#/components/schemas/SyncState"
              }
            ]
          },
          "overrides": {
            "$ref": "#/components/schemas/ClientOverrides"
          },
          "overrideCount": {
            "type": "integer"
          },
          "notes": {
            "type": "string"
          },
          "extraChecklistSteps": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ClientStepRef"
            }
          },
          "engagements": {
            "description": "Year-end history, newest first.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ClientEngagement"
            }
          }
        },
        "required": [
          "id",
          "firmId",
          "name",
          "entityType",
          "companyNumber",
          "yearEndDay",
          "yearEndMonth",
          "createdAt",
          "partnerId",
          "managerId",
          "preparerId",
          "reviewerId",
          "software",
          "syncState",
          "overrides",
          "overrideCount",
          "notes",
          "extraChecklistSteps",
          "engagements"
        ]
      },
      "ClientMapping": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string"
          },
          "name": {
            "type": [
              "string",
              "null"
            ],
            "description": "The account’s name on the latest trial balance that has it."
          },
          "lineId": {
            "allOf": [
              {
                "$ref": "#/components/schemas/LeadLineId"
              }
            ]
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "description": "A remembered mapping: applied to this client’s code ahead of the firm rules.",
        "required": [
          "code",
          "name",
          "lineId",
          "updatedAt"
        ]
      },
      "ClientNotes": {
        "type": "object",
        "properties": {
          "notes": {
            "type": "string",
            "maxLength": 20000
          },
          "updatedBy": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "updatedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          }
        },
        "required": [
          "notes",
          "updatedBy",
          "updatedAt"
        ]
      },
      "SetClientNotes": {
        "type": "object",
        "properties": {
          "notes": {
            "type": "string",
            "maxLength": 20000
          }
        },
        "required": [
          "notes"
        ]
      },
      "IntegrationProvider": {
        "type": "string",
        "enum": [
          "xero",
          "quickbooks",
          "sage",
          "freeagent"
        ]
      },
      "ConnectionCounts": {
        "type": "object",
        "properties": {
          "active": {
            "type": "integer",
            "minimum": 0
          },
          "expired": {
            "type": "integer",
            "minimum": 0,
            "description": "Refresh token lapsed or access removed: needs reconnecting."
          },
          "revoked": {
            "type": "integer",
            "minimum": 0
          },
          "error": {
            "type": "integer",
            "minimum": 0
          },
          "needsOrganisation": {
            "type": "integer",
            "minimum": 0,
            "description": "Connected, but the organisation has not been chosen yet."
          }
        },
        "required": [
          "active",
          "expired",
          "revoked",
          "error",
          "needsOrganisation"
        ]
      },
      "IntegrationProviderInfo": {
        "type": "object",
        "properties": {
          "id": {
            "allOf": [
              {
                "$ref": "#/components/schemas/IntegrationProvider"
              }
            ]
          },
          "label": {
            "type": "string",
            "example": "Xero"
          },
          "configured": {
            "type": "boolean",
            "description": "Set up for this Tolvi deployment (developer app credentials present). Only configured providers can be connected."
          },
          "connections": {
            "description": "This firm’s client connections to the provider, by status.",
            "allOf": [
              {
                "$ref": "#/components/schemas/ConnectionCounts"
              }
            ]
          }
        },
        "required": [
          "id",
          "label",
          "configured",
          "connections"
        ]
      },
      "IntegrationProviders": {
        "type": "object",
        "properties": {
          "providers": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/IntegrationProviderInfo"
            }
          },
          "fake": {
            "type": "boolean",
            "description": "Development only: the fixture-driven fake provider stands in for every provider."
          }
        },
        "required": [
          "providers",
          "fake"
        ]
      },
      "IntegrationCallbackRequest": {
        "type": "object",
        "properties": {
          "provider": {
            "allOf": [
              {
                "$ref": "#/components/schemas/IntegrationProvider"
              }
            ]
          },
          "code": {
            "type": "string",
            "minLength": 1,
            "maxLength": 4096,
            "description": "The `code` from the provider’s redirect."
          },
          "state": {
            "type": "string",
            "minLength": 1,
            "maxLength": 512,
            "description": "The `state` from the provider’s redirect."
          },
          "params": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            },
            "description": "Any other query parameters from the redirect (QuickBooks sends realmId)."
          }
        },
        "required": [
          "provider",
          "code",
          "state"
        ]
      },
      "IntegrationCallbackOutcome": {
        "type": "string",
        "enum": [
          "connected",
          "choose_organisation"
        ]
      },
      "ConnectionStatus": {
        "type": "string",
        "enum": [
          "active",
          "expired",
          "revoked",
          "error"
        ]
      },
      "ConnectionOrganisation": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "The provider’s organisation (tenant, realm, business or company) id."
          },
          "name": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "name"
        ]
      },
      "ClientConnection": {
        "type": "object",
        "properties": {
          "clientId": {
            "type": "string",
            "format": "uuid"
          },
          "connected": {
            "type": "boolean"
          },
          "provider": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/IntegrationProvider"
              },
              {
                "type": "null"
              }
            ]
          },
          "providerLabel": {
            "type": [
              "string",
              "null"
            ],
            "example": "Xero"
          },
          "status": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/ConnectionStatus"
              },
              {
                "type": "null"
              }
            ]
          },
          "orgId": {
            "type": [
              "string",
              "null"
            ]
          },
          "orgName": {
            "type": [
              "string",
              "null"
            ]
          },
          "needsOrganisation": {
            "type": "boolean",
            "description": "Several organisations were authorised: choose one with PUT …/connection/organisation."
          },
          "organisations": {
            "description": "The organisations to choose from (only while needsOrganisation).",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ConnectionOrganisation"
            }
          },
          "viaPractice": {
            "type": "boolean",
            "description": "Connected by importing clients from the practice’s Xero: the tokens are the practice authorisation’s, shared with the other clients imported with it."
          },
          "lastError": {
            "type": [
              "string",
              "null"
            ],
            "description": "The last failure, in words. Never contains a token."
          },
          "lastSyncedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "connectedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "connectedBy": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          }
        },
        "required": [
          "clientId",
          "connected",
          "provider",
          "providerLabel",
          "status",
          "orgId",
          "orgName",
          "needsOrganisation",
          "organisations",
          "viaPractice",
          "lastError",
          "lastSyncedAt",
          "connectedAt",
          "connectedBy"
        ]
      },
      "IntegrationCallbackResult": {
        "type": "object",
        "properties": {
          "clientId": {
            "type": "string",
            "format": "uuid",
            "description": "The client connected."
          },
          "grantId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid",
            "description": "Always null. Kept for compatibility: a practice connect finishes with POST /integrations/practice/callback, which returns the grantId."
          },
          "outcome": {
            "allOf": [
              {
                "$ref": "#/components/schemas/IntegrationCallbackOutcome"
              }
            ]
          },
          "connection": {
            "$ref": "#/components/schemas/ClientConnection"
          }
        },
        "required": [
          "clientId",
          "grantId",
          "outcome",
          "connection"
        ]
      },
      "PracticeProvider": {
        "type": "string",
        "enum": [
          "xero"
        ],
        "description": "Only Xero offers the organisation details the import needs."
      },
      "AuthorizePracticeRequest": {
        "type": "object",
        "properties": {
          "provider": {
            "description": "Only Xero offers the organisation details the import needs.",
            "allOf": [
              {
                "$ref": "#/components/schemas/PracticeProvider"
              }
            ]
          }
        },
        "required": [
          "provider"
        ]
      },
      "AuthorizeConnectionResult": {
        "type": "object",
        "properties": {
          "authorizeUrl": {
            "type": "string",
            "format": "uri",
            "description": "Send the user here. The provider returns them to /integrations/callback/{provider}; valid for 10 minutes, once."
          }
        },
        "required": [
          "authorizeUrl"
        ]
      },
      "PracticeCallbackRequest": {
        "type": "object",
        "properties": {
          "provider": {
            "allOf": [
              {
                "$ref": "#/components/schemas/PracticeProvider"
              }
            ]
          },
          "code": {
            "type": "string",
            "minLength": 1,
            "maxLength": 4096,
            "description": "The `code` from the provider’s redirect."
          },
          "state": {
            "type": "string",
            "minLength": 1,
            "maxLength": 512,
            "description": "The `state` from the provider’s redirect."
          },
          "params": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            },
            "description": "Any other query parameters from the redirect."
          }
        },
        "required": [
          "provider",
          "code",
          "state"
        ]
      },
      "PracticeCallbackOutcome": {
        "type": "string",
        "enum": [
          "practice_authorised"
        ]
      },
      "PracticeCallbackResult": {
        "type": "object",
        "properties": {
          "grantId": {
            "type": "string",
            "format": "uuid",
            "description": "The authorisation to import clients from (GET /integrations/practice/grants/{grantId}/organisations)."
          },
          "outcome": {
            "allOf": [
              {
                "$ref": "#/components/schemas/PracticeCallbackOutcome"
              }
            ]
          },
          "organisationCount": {
            "type": "integer",
            "minimum": 1,
            "description": "Organisations the adviser authorised."
          }
        },
        "required": [
          "grantId",
          "outcome",
          "organisationCount"
        ]
      },
      "PracticeGrant": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "provider": {
            "allOf": [
              {
                "$ref": "#/components/schemas/IntegrationProvider"
              }
            ]
          },
          "providerLabel": {
            "type": "string",
            "example": "Xero"
          },
          "status": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ConnectionStatus"
              }
            ]
          },
          "organisationCount": {
            "type": "integer",
            "minimum": 0,
            "description": "Organisations the adviser authorised."
          },
          "clientsConnected": {
            "type": "integer",
            "minimum": 0,
            "description": "Clients connected through this authorisation."
          },
          "lastError": {
            "type": [
              "string",
              "null"
            ]
          },
          "connectedAt": {
            "type": "string",
            "format": "date-time"
          },
          "connectedBy": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          }
        },
        "required": [
          "id",
          "provider",
          "providerLabel",
          "status",
          "organisationCount",
          "clientsConnected",
          "lastError",
          "connectedAt",
          "connectedBy"
        ]
      },
      "PracticeGrantList": {
        "type": "object",
        "properties": {
          "rows": {
            "description": "Newest first.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PracticeGrant"
            }
          }
        },
        "required": [
          "rows"
        ]
      },
      "PracticeClientRef": {
        "type": "object",
        "properties": {
          "clientId": {
            "type": "string",
            "format": "uuid"
          },
          "clientName": {
            "type": "string"
          }
        },
        "required": [
          "clientId",
          "clientName"
        ]
      },
      "PracticeMatchBasis": {
        "type": "string",
        "enum": [
          "company_number",
          "name"
        ]
      },
      "PracticeClientMatch": {
        "type": "object",
        "properties": {
          "clientId": {
            "type": "string",
            "format": "uuid"
          },
          "clientName": {
            "type": "string"
          },
          "matchedBy": {
            "allOf": [
              {
                "$ref": "#/components/schemas/PracticeMatchBasis"
              }
            ]
          },
          "connectedElsewhere": {
            "type": [
              "string",
              "null"
            ],
            "description": "The client is already connected to other books (it is then left as it is)."
          }
        },
        "required": [
          "clientId",
          "clientName",
          "matchedBy",
          "connectedElsewhere"
        ]
      },
      "PracticeOrganisation": {
        "type": "object",
        "properties": {
          "orgId": {
            "type": "string",
            "description": "The provider’s organisation (tenant) id."
          },
          "name": {
            "type": "string",
            "description": "The client name to use (the legal name when Xero has one)."
          },
          "legalName": {
            "type": [
              "string",
              "null"
            ]
          },
          "organisationType": {
            "type": [
              "string",
              "null"
            ],
            "description": "The provider’s own word for the legal form, e.g. COMPANY, PARTNERSHIP, SOLE_TRADER, CHARITY."
          },
          "entityType": {
            "description": "Suggested Tolvi entity type; null when Tolvi doesn’t prepare this kind of entity (choose one to import it).",
            "oneOf": [
              {
                "$ref": "#/components/schemas/EntityType"
              },
              {
                "type": "null"
              }
            ]
          },
          "entityTypeReason": {
            "type": "string"
          },
          "companyNumber": {
            "type": [
              "string",
              "null"
            ],
            "description": "Companies House number, normalised (companies and LLPs only)."
          },
          "vatNumber": {
            "type": [
              "string",
              "null"
            ],
            "description": "VAT number as held in Xero."
          },
          "yearEndDay": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 1,
            "maximum": 31
          },
          "yearEndMonth": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 1,
            "maximum": 12
          },
          "nextPeriodEnd": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31",
            "description": "The first year end on or after today (29 February becomes 28 February outside leap years)."
          },
          "baseCurrency": {
            "type": [
              "string",
              "null"
            ]
          },
          "isDemoCompany": {
            "type": "boolean"
          },
          "warnings": {
            "description": "Reasons it isn’t ticked by default.",
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "profileError": {
            "type": [
              "string",
              "null"
            ],
            "description": "Why the organisation’s details couldn’t be read (not importable until reconnected)."
          },
          "connectedClient": {
            "description": "Already connected to this Tolvi client.",
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/PracticeClientRef"
              }
            ]
          },
          "match": {
            "description": "Already in Tolvi: importing links to this client instead of creating one.",
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/PracticeClientMatch"
              }
            ]
          },
          "suggested": {
            "type": "boolean",
            "description": "Pre-tick it: new to Tolvi, a type Tolvi prepares and nothing to check."
          }
        },
        "required": [
          "orgId",
          "name",
          "legalName",
          "organisationType",
          "entityType",
          "entityTypeReason",
          "companyNumber",
          "vatNumber",
          "yearEndDay",
          "yearEndMonth",
          "nextPeriodEnd",
          "baseCurrency",
          "isDemoCompany",
          "warnings",
          "profileError",
          "connectedClient",
          "match",
          "suggested"
        ]
      },
      "PracticeOrganisationList": {
        "type": "object",
        "properties": {
          "grant": {
            "$ref": "#/components/schemas/PracticeGrant"
          },
          "organisations": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PracticeOrganisation"
            }
          }
        },
        "required": [
          "grant",
          "organisations"
        ]
      },
      "PracticeImportItem": {
        "type": "object",
        "properties": {
          "orgId": {
            "type": "string",
            "minLength": 1,
            "maxLength": 200
          },
          "entityType": {
            "description": "For a new client; defaults to the suggestion. Ignored when linking.",
            "allOf": [
              {
                "$ref": "#/components/schemas/EntityType"
              }
            ]
          },
          "yearEndDay": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 1,
            "maximum": 31,
            "description": "Year end day (with yearEndMonth); defaults to none."
          },
          "yearEndMonth": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 1,
            "maximum": 12
          },
          "clientId": {
            "type": "string",
            "format": "uuid",
            "description": "Link to this existing client instead of matching."
          },
          "createNew": {
            "type": "boolean",
            "description": "Create a new client even if one matches."
          }
        },
        "required": [
          "orgId"
        ]
      },
      "PracticeImportRequest": {
        "type": "object",
        "properties": {
          "organisations": {
            "minItems": 1,
            "maxItems": 1000,
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PracticeImportItem"
            }
          }
        },
        "required": [
          "organisations"
        ]
      },
      "PracticeImportOutcomeKind": {
        "type": "string",
        "enum": [
          "created",
          "linked",
          "already_connected",
          "skipped"
        ]
      },
      "PracticeImportOutcome": {
        "type": "object",
        "properties": {
          "orgId": {
            "type": "string"
          },
          "orgName": {
            "type": "string"
          },
          "outcome": {
            "allOf": [
              {
                "$ref": "#/components/schemas/PracticeImportOutcomeKind"
              }
            ]
          },
          "clientId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "clientName": {
            "type": [
              "string",
              "null"
            ]
          },
          "reason": {
            "type": [
              "string",
              "null"
            ],
            "description": "Why it was skipped."
          }
        },
        "required": [
          "orgId",
          "orgName",
          "outcome",
          "clientId",
          "clientName",
          "reason"
        ]
      },
      "PracticeImportResult": {
        "type": "object",
        "properties": {
          "created": {
            "type": "integer",
            "minimum": 0
          },
          "linked": {
            "type": "integer",
            "minimum": 0
          },
          "alreadyConnected": {
            "type": "integer",
            "minimum": 0
          },
          "skipped": {
            "type": "integer",
            "minimum": 0
          },
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PracticeImportOutcome"
            }
          }
        },
        "required": [
          "created",
          "linked",
          "alreadyConnected",
          "skipped",
          "results"
        ]
      },
      "AuthorizeConnectionRequest": {
        "type": "object",
        "properties": {
          "provider": {
            "allOf": [
              {
                "$ref": "#/components/schemas/IntegrationProvider"
              }
            ]
          }
        },
        "required": [
          "provider"
        ]
      },
      "ChooseOrganisationRequest": {
        "type": "object",
        "properties": {
          "orgId": {
            "type": "string",
            "minLength": 1,
            "maxLength": 200
          }
        },
        "required": [
          "orgId"
        ]
      },
      "BooksSource": {
        "type": "string",
        "enum": [
          "xero",
          "quickbooks",
          "sage",
          "freeagent",
          "tolvi_books"
        ],
        "description": "Null when the client has no connection and no Tolvi Books link."
      },
      "BooksSourcePick": {
        "type": "string",
        "enum": [
          "tolvi_books",
          "connection"
        ],
        "description": "What to send as `use` to PUT /clients/{clientId}/books-link/source."
      },
      "TbPullSourceChoice": {
        "type": "object",
        "properties": {
          "use": {
            "description": "What to send as `use` to PUT /clients/{clientId}/books-link/source.",
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksSourcePick"
              }
            ]
          },
          "source": {
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksSource"
              }
            ]
          },
          "label": {
            "type": "string",
            "example": "Tolvi Books"
          },
          "organisationName": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "description": "One of the two sources a client with both can use.",
        "required": [
          "use",
          "source",
          "label",
          "organisationName"
        ]
      },
      "TbPullSource": {
        "type": "object",
        "properties": {
          "engagementId": {
            "type": "string",
            "format": "uuid"
          },
          "source": {
            "description": "Null when the client has no connection and no Tolvi Books link.",
            "oneOf": [
              {
                "$ref": "#/components/schemas/BooksSource"
              },
              {
                "type": "null"
              }
            ]
          },
          "label": {
            "type": [
              "string",
              "null"
            ],
            "example": "Tolvi Books"
          },
          "organisationName": {
            "type": [
              "string",
              "null"
            ]
          },
          "available": {
            "type": "boolean",
            "description": "A pull can be made now."
          },
          "reason": {
            "type": [
              "string",
              "null"
            ],
            "description": "Why not, in words, when it can’t."
          },
          "needsChoice": {
            "type": "boolean",
            "description": "The client has both sources and nobody has chosen which its engagements use."
          },
          "choices": {
            "description": "The two to choose from when needsChoice; empty otherwise.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TbPullSourceChoice"
            }
          }
        },
        "description": "Which source a pull for this engagement reads: the client’s only source, or, when it has both an OAuth connection and a Tolvi Books link, the one a person chose. Until someone chooses, `needsChoice` is true and `choices` lists both: Tolvi asks rather than guessing.",
        "required": [
          "engagementId",
          "source",
          "label",
          "organisationName",
          "available",
          "reason",
          "needsChoice",
          "choices"
        ]
      },
      "TbPullPreview": {
        "type": "object",
        "properties": {
          "accountCount": {
            "type": "integer"
          },
          "addedCodes": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "removedCodes": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "changedCount": {
            "type": "integer",
            "description": "Accounts whose balances differ from the current version."
          },
          "cyTotalPence": {
            "type": "integer",
            "description": "Integer pence (GBP)."
          },
          "balanced": {
            "type": "boolean"
          },
          "hash": {
            "type": "string"
          },
          "sameAsCurrent": {
            "type": "boolean",
            "description": "Identical to the current version (an import would be refused)."
          },
          "journalsToRemove": {
            "description": "Journals whose accounts are not in the new TB: confirm before they are removed.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/JournalRef"
            }
          },
          "unmappedCount": {
            "type": "integer",
            "description": "Accounts nothing could map."
          },
          "debitTotalPence": {
            "type": "integer",
            "description": "Current year debit balances added up, in integer pence."
          },
          "creditTotalPence": {
            "type": "integer",
            "description": "Current year credit balances added up, in integer pence (negative)."
          },
          "accounts": {
            "description": "The accounts as read, in file order.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TbPreviewAccount"
            }
          },
          "warnings": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TbWarning"
            }
          },
          "layout": {
            "description": "The header row and columns read (detected, or as given in `columns`). Null for structured accounts.",
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/TbColumns"
              }
            ]
          },
          "staleSignOffs": {
            "description": "Sections whose current sign-offs this import would put out of date.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TbStaleSignOff"
            }
          },
          "importLock": {
            "description": "Set when the file is signed off at every stage: the import is refused unless it reopens the file.",
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/TbImportLock"
              }
            ]
          },
          "provider": {
            "description": "Where the trial balance was read: an OAuth provider, or tolvi_books (the client’s Tolvi Books, through the firm’s practice link).",
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksSource"
              }
            ]
          },
          "sourceLabel": {
            "type": "string",
            "example": "Tolvi Books"
          },
          "organisationName": {
            "type": "string",
            "description": "The organisation (OAuth) or business (Tolvi Books) read."
          },
          "booksThroughSeq": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Tolvi Books: the ledger point read (the last entry included). Null for other sources."
          },
          "asAt": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31",
            "description": "The period end: the current year column."
          },
          "priorAsAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31",
            "description": "The prior period end: the prior year column (null for a first period)."
          }
        },
        "required": [
          "accountCount",
          "addedCodes",
          "removedCodes",
          "changedCount",
          "cyTotalPence",
          "balanced",
          "hash",
          "sameAsCurrent",
          "journalsToRemove",
          "unmappedCount",
          "debitTotalPence",
          "creditTotalPence",
          "accounts",
          "warnings",
          "layout",
          "staleSignOffs",
          "provider",
          "sourceLabel",
          "organisationName",
          "booksThroughSeq",
          "asAt",
          "priorAsAt"
        ]
      },
      "TbPullRequest": {
        "type": "object",
        "properties": {
          "expectedHash": {
            "type": "string",
            "description": "The hash from the preview. If the books have changed since, nothing is imported (409) and you preview again."
          },
          "confirmJournalRemoval": {
            "type": "boolean",
            "description": "Confirm removing the journals the preview listed."
          },
          "reopenFile": {
            "type": "boolean",
            "description": "Required to pull into a file signed off at every stage: the import reopens it for re-approval (reviewer or above). See `TbImport.reopenFile`."
          }
        }
      },
      "ChartOfAccountsSource": {
        "type": "string",
        "enum": [
          "xero",
          "quickbooks",
          "sage",
          "freeagent",
          "tolvi_books",
          "csv"
        ],
        "description": "Null until a chart has been read or imported."
      },
      "ChartAccountType": {
        "type": "string",
        "enum": [
          "asset",
          "liability",
          "equity",
          "revenue",
          "expense"
        ]
      },
      "ChartAccount": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "type": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/ChartAccountType"
              },
              {
                "type": "null"
              }
            ]
          },
          "providerType": {
            "type": [
              "string",
              "null"
            ],
            "description": "The software’s own type, e.g. Xero’s FIXED or DEPRECIATN, or the CSV’s Type column."
          },
          "active": {
            "type": "boolean",
            "description": "False for archived or inactive accounts."
          },
          "lineId": {
            "description": "The lead schedule line the mapping order suggests (client memory, firm rules, built-in).",
            "oneOf": [
              {
                "$ref": "#/components/schemas/LeadLineId"
              },
              {
                "type": "null"
              }
            ]
          }
        },
        "description": "One account on the client’s chart of accounts, with or without a balance.",
        "required": [
          "code",
          "name",
          "type",
          "providerType",
          "active",
          "lineId"
        ]
      },
      "ChartOfAccounts": {
        "type": "object",
        "properties": {
          "clientId": {
            "type": "string",
            "format": "uuid"
          },
          "source": {
            "description": "Null until a chart has been read or imported.",
            "oneOf": [
              {
                "$ref": "#/components/schemas/ChartOfAccountsSource"
              },
              {
                "type": "null"
              }
            ]
          },
          "sourceLabel": {
            "type": [
              "string",
              "null"
            ],
            "example": "Xero"
          },
          "syncedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "When the chart was last read or imported."
          },
          "canRefresh": {
            "type": "boolean",
            "description": "The client’s books are connected (or linked to Tolvi Books), so POST …/chart-of-accounts/refresh can read the chart again."
          },
          "accounts": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ChartAccount"
            }
          }
        },
        "description": "The client’s chart of accounts, read from their bookkeeping software (on connect, on every TB pull, and on refresh) or imported from a CSV.",
        "required": [
          "clientId",
          "source",
          "sourceLabel",
          "syncedAt",
          "canRefresh",
          "accounts"
        ]
      },
      "ChartOfAccountsFormat": {
        "type": "string",
        "enum": [
          "csv"
        ]
      },
      "ImportChartOfAccountsRequest": {
        "type": "object",
        "properties": {
          "format": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ChartOfAccountsFormat"
              }
            ]
          },
          "content": {
            "type": "string",
            "maxLength": 2000000,
            "description": "The CSV text: Code and Name columns, with Type and Status where the file has them (Xero’s chart of accounts export works as it is)."
          }
        },
        "required": [
          "format",
          "content"
        ]
      },
      "SyncCounts": {
        "type": "object",
        "properties": {
          "connected": {
            "type": "integer",
            "minimum": 0,
            "description": "Engagements on bookkeeping software (open, plus completed ones still checked)."
          },
          "manual": {
            "type": "integer",
            "minimum": 0
          },
          "inSync": {
            "type": "integer",
            "minimum": 0
          },
          "changed": {
            "type": "integer",
            "minimum": 0,
            "description": "Open engagements whose figures changed since sign-off (the Work queue’s Changed view)."
          },
          "changedCompleted": {
            "type": "integer",
            "minimum": 0,
            "description": "Completed engagements whose figures changed."
          },
          "expired": {
            "type": "integer",
            "minimum": 0
          },
          "error": {
            "type": "integer",
            "minimum": 0
          },
          "neverSynced": {
            "type": "integer",
            "minimum": 0
          },
          "manualOpen": {
            "type": "integer",
            "minimum": 0,
            "description": "Open engagements on manual upload: not checkable."
          },
          "resolvedToday": {
            "type": "integer",
            "minimum": 0,
            "description": "Accepted, acknowledged or recorded as post-filing today (firm time zone)."
          }
        },
        "required": [
          "connected",
          "manual",
          "inSync",
          "changed",
          "changedCompleted",
          "expired",
          "error",
          "neverSynced",
          "manualOpen",
          "resolvedToday"
        ]
      },
      "SyncCheckTrigger": {
        "type": "string",
        "enum": [
          "schedule",
          "manual"
        ],
        "description": "schedule: the nightly or weekly run; manual: Run check now."
      },
      "SyncCheckRun": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "trigger": {
            "description": "schedule: the nightly or weekly run; manual: Run check now.",
            "allOf": [
              {
                "$ref": "#/components/schemas/SyncCheckTrigger"
              }
            ]
          },
          "startedAt": {
            "type": "string",
            "format": "date-time"
          },
          "finishedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "Null while engagements are still being checked."
          },
          "windowStart": {
            "type": "string",
            "format": "date-time",
            "description": "Checks start from here; a scheduled run spreads them over windowMinutes."
          },
          "windowMinutes": {
            "type": "integer",
            "minimum": 0
          },
          "total": {
            "type": "integer",
            "minimum": 0,
            "description": "Engagements in scope."
          },
          "checked": {
            "type": "integer",
            "minimum": 0,
            "description": "Engagements checked so far."
          },
          "changed": {
            "type": "integer",
            "minimum": 0
          },
          "failed": {
            "type": "integer",
            "minimum": 0,
            "description": "Expired connections and errors."
          },
          "durationMinutes": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 0,
            "description": "From start to finish."
          },
          "requestedBy": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          }
        },
        "required": [
          "id",
          "trigger",
          "startedAt",
          "finishedAt",
          "windowStart",
          "windowMinutes",
          "total",
          "checked",
          "changed",
          "failed",
          "durationMinutes",
          "requestedBy"
        ]
      },
      "SyncSchedule": {
        "type": "object",
        "properties": {
          "frequency": {
            "allOf": [
              {
                "$ref": "#/components/schemas/SyncFrequency"
              }
            ]
          },
          "time": {
            "type": "string",
            "example": "02:00"
          },
          "timeZone": {
            "type": "string",
            "example": "Europe/London"
          },
          "ignoreUnderPence": {
            "type": "integer",
            "minimum": 0,
            "description": "Movements smaller than this are ignored (firm default; a client can override it)."
          },
          "comparePriorYear": {
            "type": "boolean"
          },
          "onChange": {
            "allOf": [
              {
                "$ref": "#/components/schemas/SyncOnChange"
              }
            ]
          },
          "digest": {
            "allOf": [
              {
                "$ref": "#/components/schemas/SyncDigest"
              }
            ]
          }
        },
        "required": [
          "frequency",
          "time",
          "timeZone",
          "ignoreUnderPence",
          "comparePriorYear",
          "onChange",
          "digest"
        ]
      },
      "SyncSoftwareRow": {
        "type": "object",
        "properties": {
          "software": {
            "allOf": [
              {
                "$ref": "#/components/schemas/Software"
              }
            ]
          },
          "engagements": {
            "type": "integer",
            "minimum": 0
          },
          "inSync": {
            "type": "integer",
            "minimum": 0
          },
          "changed": {
            "type": "integer",
            "minimum": 0
          },
          "fix": {
            "type": "integer",
            "minimum": 0,
            "description": "Expired, error or never synced."
          }
        },
        "required": [
          "software",
          "engagements",
          "inSync",
          "changed",
          "fix"
        ]
      },
      "SyncOverview": {
        "type": "object",
        "properties": {
          "counts": {
            "$ref": "#/components/schemas/SyncCounts"
          },
          "lastRun": {
            "description": "The last run that finished.",
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/SyncCheckRun"
              }
            ]
          },
          "running": {
            "description": "A run still checking engagements.",
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/SyncCheckRun"
              }
            ]
          },
          "schedule": {
            "$ref": "#/components/schemas/SyncSchedule"
          },
          "bySoftware": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SyncSoftwareRow"
            }
          }
        },
        "required": [
          "counts",
          "lastRun",
          "running",
          "schedule",
          "bySoftware"
        ]
      },
      "SyncList": {
        "type": "string",
        "enum": [
          "changed",
          "fix",
          "manual",
          "resolved"
        ]
      },
      "SyncCheckStatus": {
        "type": "string",
        "enum": [
          "running",
          "in_sync",
          "changed",
          "acknowledged",
          "expired_token",
          "error"
        ]
      },
      "SyncResolution": {
        "type": "string",
        "enum": [
          "accepted",
          "acknowledged",
          "post_filing"
        ]
      },
      "SyncResultSummary": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "status": {
            "allOf": [
              {
                "$ref": "#/components/schemas/SyncCheckStatus"
              }
            ]
          },
          "checkedAt": {
            "type": "string",
            "format": "date-time"
          },
          "signedOffAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "accountCount": {
            "type": "integer",
            "minimum": 0,
            "description": "Accounts that moved."
          },
          "grossPence": {
            "type": "integer",
            "minimum": 0,
            "description": "Sum of the absolute current year movements."
          },
          "affectedSections": {
            "description": "Affected lead sections (W/P refs).",
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "resolution": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/SyncResolution"
              },
              {
                "type": "null"
              }
            ]
          },
          "resolvedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "outcome": {
            "type": [
              "string",
              "null"
            ],
            "description": "The outcome in words (who resolved it and how)."
          },
          "message": {
            "type": [
              "string",
              "null"
            ],
            "description": "Why the check could not run, in words."
          }
        },
        "required": [
          "id",
          "status",
          "checkedAt",
          "signedOffAt",
          "accountCount",
          "grossPence",
          "affectedSections",
          "resolution",
          "resolvedAt",
          "outcome",
          "message"
        ]
      },
      "SyncRow": {
        "type": "object",
        "properties": {
          "engagementId": {
            "type": "string",
            "format": "uuid"
          },
          "clientId": {
            "type": "string",
            "format": "uuid"
          },
          "clientName": {
            "type": "string"
          },
          "entityType": {
            "allOf": [
              {
                "$ref": "#/components/schemas/EntityType"
              }
            ]
          },
          "periodEnd": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "dueDate": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "status": {
            "allOf": [
              {
                "$ref": "#/components/schemas/EngagementStatus"
              }
            ]
          },
          "software": {
            "allOf": [
              {
                "$ref": "#/components/schemas/Software"
              }
            ]
          },
          "syncState": {
            "allOf": [
              {
                "$ref": "#/components/schemas/SyncState"
              }
            ]
          },
          "lastSyncedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "result": {
            "description": "The latest sign-off check result.",
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/SyncResultSummary"
              }
            ]
          }
        },
        "required": [
          "engagementId",
          "clientId",
          "clientName",
          "entityType",
          "periodEnd",
          "dueDate",
          "status",
          "software",
          "syncState",
          "lastSyncedAt",
          "result"
        ]
      },
      "SyncRowPage": {
        "type": "object",
        "properties": {
          "list": {
            "allOf": [
              {
                "$ref": "#/components/schemas/SyncList"
              }
            ]
          },
          "rows": {
            "description": "Earliest deadline first; at most `limit`.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SyncRow"
            }
          },
          "total": {
            "type": "integer",
            "minimum": 0
          }
        },
        "required": [
          "list",
          "rows",
          "total"
        ]
      },
      "StartSyncCheckRequest": {
        "type": "object",
        "properties": {
          "engagementIds": {
            "description": "Only these engagements (Work queue bulk action); default every engagement in scope.",
            "maxItems": 500,
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        }
      },
      "SyncRemindersRequest": {
        "type": "object",
        "properties": {
          "engagementIds": {
            "description": "Engagements whose bookkeeping connection needs reconnecting or fixing (Sync health’s Reconnect or fix list).",
            "minItems": 1,
            "maxItems": 500,
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        },
        "required": [
          "engagementIds"
        ]
      },
      "SyncReminders": {
        "type": "object",
        "properties": {
          "notified": {
            "type": "integer",
            "minimum": 0,
            "description": "People sent a reminder (one each, listing their clients)."
          },
          "engagements": {
            "type": "integer",
            "minimum": 0,
            "description": "Engagements covered by a reminder."
          },
          "skipped": {
            "type": "integer",
            "minimum": 0,
            "description": "Engagements left out: not broken, on manual upload, or with nobody to remind but you."
          }
        },
        "description": "Who was reminded.",
        "required": [
          "notified",
          "engagements",
          "skipped"
        ]
      },
      "SyncDiffStatus": {
        "type": "string",
        "enum": [
          "changed",
          "added",
          "removed"
        ]
      },
      "SyncBalances": {
        "type": "object",
        "properties": {
          "cyPence": {
            "type": "integer"
          },
          "pyPence": {
            "type": "integer"
          }
        },
        "required": [
          "cyPence",
          "pyPence"
        ]
      },
      "SyncTransaction": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "The provider’s id for the source document or journal."
          },
          "accountCode": {
            "type": "string"
          },
          "date": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "description": {
            "type": "string"
          },
          "amountPence": {
            "type": "integer",
            "description": "Debit positive."
          },
          "updatedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "When it was entered or last changed in the software."
          },
          "sourceType": {
            "type": [
              "string",
              "null"
            ]
          },
          "postedBy": {
            "type": [
              "string",
              "null"
            ],
            "description": "Who entered it, when the software says (Tolvi Books does).",
            "example": "Jo Owner (the business)"
          },
          "explanation": {
            "type": "string",
            "example": "Credit note CN-0192 (Kestrel Homes), dated 28 Mar 2026, entered 14 Oct 2026"
          }
        },
        "required": [
          "id",
          "accountCode",
          "date",
          "description",
          "amountPence",
          "updatedAt",
          "sourceType",
          "postedBy",
          "explanation"
        ]
      },
      "SyncDiffAccount": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "status": {
            "allOf": [
              {
                "$ref": "#/components/schemas/SyncDiffStatus"
              }
            ]
          },
          "signedOff": {
            "description": "In the trial balance that was signed off.",
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/SyncBalances"
              }
            ]
          },
          "now": {
            "description": "In the bookkeeping software now.",
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/SyncBalances"
              }
            ]
          },
          "cyDiffPence": {
            "type": "integer"
          },
          "pyDiffPence": {
            "type": "integer"
          },
          "sections": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "transactions": {
            "description": "Postings behind the movement, when the software lists them.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SyncTransaction"
            }
          },
          "unexplainedPence": {
            "type": "integer",
            "description": "The movement the transactions do not account for."
          }
        },
        "required": [
          "code",
          "name",
          "status",
          "signedOff",
          "now",
          "cyDiffPence",
          "pyDiffPence",
          "sections",
          "transactions",
          "unexplainedPence"
        ]
      },
      "SyncCheckResult": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "status": {
            "allOf": [
              {
                "$ref": "#/components/schemas/SyncCheckStatus"
              }
            ]
          },
          "checkedAt": {
            "type": "string",
            "format": "date-time"
          },
          "signedOffAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "accountCount": {
            "type": "integer",
            "minimum": 0,
            "description": "Accounts that moved."
          },
          "grossPence": {
            "type": "integer",
            "minimum": 0,
            "description": "Sum of the absolute current year movements."
          },
          "affectedSections": {
            "description": "Affected lead sections (W/P refs).",
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "resolution": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/SyncResolution"
              },
              {
                "type": "null"
              }
            ]
          },
          "resolvedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "outcome": {
            "type": [
              "string",
              "null"
            ],
            "description": "The outcome in words (who resolved it and how)."
          },
          "message": {
            "type": [
              "string",
              "null"
            ],
            "description": "Why the check could not run, in words."
          },
          "runId": {
            "type": "string",
            "format": "uuid"
          },
          "provider": {
            "description": "The OAuth provider read; null for Tolvi Books (see source).",
            "oneOf": [
              {
                "$ref": "#/components/schemas/IntegrationProvider"
              },
              {
                "type": "null"
              }
            ]
          },
          "source": {
            "description": "Where the books were read: an OAuth provider, or tolvi_books (the client’s Tolvi Books, through the firm’s practice link).",
            "oneOf": [
              {
                "$ref": "#/components/schemas/BooksSource"
              },
              {
                "type": "null"
              }
            ]
          },
          "sourceLabel": {
            "type": [
              "string",
              "null"
            ],
            "example": "Tolvi Books"
          },
          "tbVersionId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid",
            "description": "The trial balance version compared against."
          },
          "tbVersion": {
            "type": [
              "integer",
              "null"
            ]
          },
          "asAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31"
          },
          "priorAsAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31"
          },
          "accounts": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SyncDiffAccount"
            }
          },
          "transactionsAvailable": {
            "type": "boolean",
            "description": "The software could list the transactions behind the movements. From Tolvi Books they are exactly the ledger entries posted after the signed-off trial balance’s ledger point, each with who posted it."
          },
          "reason": {
            "type": [
              "string",
              "null"
            ]
          },
          "note": {
            "type": [
              "string",
              "null"
            ]
          },
          "resolvedBy": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "resolvedTbVersionId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid",
            "description": "Accept and re-sync: the trial balance version created."
          }
        },
        "required": [
          "id",
          "status",
          "checkedAt",
          "signedOffAt",
          "accountCount",
          "grossPence",
          "affectedSections",
          "resolution",
          "resolvedAt",
          "outcome",
          "message",
          "runId",
          "provider",
          "source",
          "sourceLabel",
          "tbVersionId",
          "tbVersion",
          "asAt",
          "priorAsAt",
          "accounts",
          "transactionsAvailable",
          "reason",
          "note",
          "resolvedBy",
          "resolvedTbVersionId"
        ]
      },
      "SyncCheckDetail": {
        "type": "object",
        "properties": {
          "engagementId": {
            "type": "string",
            "format": "uuid"
          },
          "clientName": {
            "type": "string"
          },
          "periodEnd": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "status": {
            "allOf": [
              {
                "$ref": "#/components/schemas/EngagementStatus"
              }
            ]
          },
          "filedOn": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31",
            "description": "When the accounts were filed; a change after that is a post-filing change."
          },
          "software": {
            "allOf": [
              {
                "$ref": "#/components/schemas/Software"
              }
            ]
          },
          "syncState": {
            "allOf": [
              {
                "$ref": "#/components/schemas/SyncState"
              }
            ]
          },
          "latest": {
            "description": "The latest result; null if never checked.",
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/SyncCheckResult"
              }
            ]
          },
          "history": {
            "description": "Earlier resolved results, newest first (the engagement’s sync history).",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SyncResultSummary"
            }
          },
          "canResolve": {
            "type": "boolean",
            "description": "Accept and re-sync, Acknowledge or Record as post-filing change can be used now."
          }
        },
        "required": [
          "engagementId",
          "clientName",
          "periodEnd",
          "status",
          "filedOn",
          "software",
          "syncState",
          "latest",
          "history",
          "canResolve"
        ]
      },
      "AcceptSyncChangeRequest": {
        "type": "object",
        "properties": {
          "confirmJournalRemoval": {
            "type": "boolean",
            "description": "Confirm removing journals on accounts no longer in the books (409 lists them otherwise)."
          }
        }
      },
      "AcknowledgeSyncChangeRequest": {
        "type": "object",
        "properties": {
          "reason": {
            "type": "string",
            "minLength": 1,
            "maxLength": 200,
            "example": "Posted in error by client; they will reverse it"
          },
          "note": {
            "type": "string",
            "maxLength": 2000,
            "description": "Required when the reason is “Other”. Shown in the sync history."
          }
        },
        "required": [
          "reason"
        ]
      },
      "PostFilingChangeRequest": {
        "type": "object",
        "properties": {
          "note": {
            "type": "string",
            "maxLength": 2000
          }
        }
      },
      "WorkingPaperExportOptions": {
        "type": "object",
        "properties": {
          "sections": {
            "maxItems": 30,
            "description": "Section codes (W/P refs) to include, in file order. Omit for every section.",
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "evidence": {
            "type": "boolean",
            "description": "The appendix listing evidence files with their checksums. Default true."
          },
          "reviewPoints": {
            "type": "boolean",
            "description": "Review point threads (the review point log), on each section and the engagement. Default true."
          },
          "auditTrail": {
            "type": "boolean",
            "description": "The review history and workflow timeline (the audit trail of sign-offs, approvals, returns and declarations). Default true."
          }
        },
        "description": "What the file contains. Everything is included unless left out here."
      },
      "WorkingPaperExportStatus": {
        "type": "string",
        "enum": [
          "queued",
          "rendering",
          "ready",
          "failed"
        ]
      },
      "WorkingPaperExport": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "engagementId": {
            "type": "string",
            "format": "uuid"
          },
          "version": {
            "type": "integer",
            "description": "1, 2, 3… per engagement."
          },
          "status": {
            "allOf": [
              {
                "$ref": "#/components/schemas/WorkingPaperExportStatus"
              }
            ]
          },
          "requestedBy": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "requestedAt": {
            "type": "string",
            "format": "date-time"
          },
          "startedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "completedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "error": {
            "type": [
              "string",
              "null"
            ],
            "description": "Why rendering failed."
          },
          "fileName": {
            "type": [
              "string",
              "null"
            ]
          },
          "sizeBytes": {
            "type": [
              "integer",
              "null"
            ]
          },
          "sha256": {
            "type": [
              "string",
              "null"
            ],
            "description": "Hex SHA-256 of the PDF."
          },
          "pageCount": {
            "type": [
              "integer",
              "null"
            ]
          },
          "outdated": {
            "type": "boolean",
            "description": "Ready, but the engagement has been signed or changed since."
          },
          "outdatedReasons": {
            "description": "What changed since the file was generated, oldest first.",
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "draft": {
            "type": [
              "string",
              "null"
            ],
            "description": "Ready, but not fully signed off when generated: the draft notice printed on its cover and footer, such as \"Draft – not signed off: 15 of 16 sections not signed off.\" Null when it was signed off (or generated before this was recorded)."
          },
          "unsignedSections": {
            "type": "integer",
            "minimum": 0,
            "description": "With draft: how many sections were not signed off at every stage (0 when only the engagement approval was missing)."
          },
          "options": {
            "description": "What was asked for; null for the whole file.",
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/WorkingPaperExportOptions"
              }
            ]
          }
        },
        "description": "One generated working paper file (PDF), versioned per engagement. Rendered in the background: poll until status is ready (or failed). A ready file is outdated once a section is signed, approved, returned or reopened, or its content changes, after it was generated.",
        "required": [
          "id",
          "engagementId",
          "version",
          "status",
          "requestedBy",
          "requestedAt",
          "startedAt",
          "completedAt",
          "error",
          "fileName",
          "sizeBytes",
          "sha256",
          "pageCount",
          "outdated",
          "outdatedReasons",
          "draft",
          "unsignedSections"
        ]
      },
      "AiFeature": {
        "type": "string",
        "enum": [
          "explain_movements",
          "suggest_mappings",
          "review_assistant",
          "check_evidence",
          "explain_sync_changes",
          "ask_tolvi",
          "draft_client_queries",
          "summarise_meeting",
          "sa_assistant",
          "sa_read_document",
          "accounts_draft_note"
        ]
      },
      "AiSuggestionStatus": {
        "type": "string",
        "enum": [
          "proposed",
          "accepted",
          "discarded"
        ]
      },
      "AiSuggestion": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "feature": {
            "allOf": [
              {
                "$ref": "#/components/schemas/AiFeature"
              }
            ]
          },
          "engagementId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "sectionCode": {
            "type": [
              "string",
              "null"
            ]
          },
          "output": {
            "type": "object",
            "additionalProperties": true,
            "description": "The feature’s structured output (see @tolvi/ai output schemas)."
          },
          "tokens": {
            "type": "integer",
            "description": "Tolvi AI tokens charged."
          },
          "model": {
            "type": "string"
          },
          "promptVersion": {
            "type": "string"
          },
          "status": {
            "allOf": [
              {
                "$ref": "#/components/schemas/AiSuggestionStatus"
              }
            ]
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "decidedBy": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "decidedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "estimate": {
            "type": "integer",
            "description": "The estimate shown before running."
          }
        },
        "description": "An AI draft. A person accepts (then applies it through the normal endpoints) or discards it.",
        "required": [
          "id",
          "feature",
          "engagementId",
          "sectionCode",
          "output",
          "tokens",
          "model",
          "promptVersion",
          "status",
          "createdAt",
          "decidedBy",
          "decidedAt"
        ]
      },
      "AiModel": {
        "type": "string",
        "enum": [
          "claude-opus-5-5",
          "claude-sonnet-5-5",
          "claude-haiku-5-5",
          "claude-sonnet-4-6",
          "claude-opus-4-6"
        ]
      },
      "AiAffordReason": {
        "type": "string",
        "enum": [
          "balance",
          "limit"
        ]
      },
      "AiEstimate": {
        "type": "object",
        "properties": {
          "feature": {
            "allOf": [
              {
                "$ref": "#/components/schemas/AiFeature"
              }
            ]
          },
          "model": {
            "allOf": [
              {
                "$ref": "#/components/schemas/AiModel"
              }
            ]
          },
          "tokens": {
            "type": "integer",
            "description": "Tolvi AI tokens."
          },
          "inputTokens": {
            "type": "integer"
          },
          "expectedOutputTokens": {
            "type": "integer"
          },
          "affordable": {
            "type": "boolean"
          },
          "reason": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/AiAffordReason"
              },
              {
                "type": "null"
              }
            ]
          }
        },
        "description": "“≈ 4,000 tokens”: shown on the AI button before running.",
        "required": [
          "feature",
          "model",
          "tokens",
          "inputTokens",
          "expectedOutputTokens",
          "affordable",
          "reason"
        ]
      },
      "AiBalanceLevel": {
        "type": "string",
        "enum": [
          "ok",
          "low",
          "critical"
        ]
      },
      "AiTokenExpiry": {
        "type": "object",
        "properties": {
          "tokens": {
            "type": "integer"
          },
          "on": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "tokens",
          "on"
        ]
      },
      "AiBalance": {
        "type": "object",
        "properties": {
          "balance": {
            "type": "integer",
            "description": "Tokens available now (unexpired)."
          },
          "held": {
            "type": "integer",
            "description": "Held for calls in progress."
          },
          "spendable": {
            "type": "integer"
          },
          "capacity": {
            "type": "integer",
            "description": "Original size of the live lots (for the 20% / 5% alerts)."
          },
          "level": {
            "allOf": [
              {
                "$ref": "#/components/schemas/AiBalanceLevel"
              }
            ]
          },
          "nextExpiry": {
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/AiTokenExpiry"
              }
            ]
          },
          "usedThisMonth": {
            "type": "integer"
          },
          "myUsedThisMonth": {
            "type": "integer"
          },
          "myLimit": {
            "type": [
              "integer",
              "null"
            ]
          },
          "enabled": {
            "type": "boolean"
          }
        },
        "required": [
          "balance",
          "held",
          "spendable",
          "capacity",
          "level",
          "nextExpiry",
          "usedThisMonth",
          "myUsedThisMonth",
          "myLimit",
          "enabled"
        ]
      },
      "AiUsageGroupBy": {
        "type": "string",
        "enum": [
          "month",
          "user",
          "feature",
          "engagement",
          "model"
        ]
      },
      "AiUsageGroup": {
        "type": "object",
        "properties": {
          "key": {
            "type": "string"
          },
          "label": {
            "type": "string"
          },
          "tokens": {
            "type": "integer",
            "description": "Tolvi AI tokens charged."
          },
          "calls": {
            "type": "integer"
          },
          "inputTokens": {
            "type": "integer"
          },
          "outputTokens": {
            "type": "integer"
          },
          "providerCostPence": {
            "type": "integer",
            "description": "Provider cost in pence (at the configured exchange rate)."
          }
        },
        "required": [
          "key",
          "label",
          "tokens",
          "calls",
          "inputTokens",
          "outputTokens",
          "providerCostPence"
        ]
      },
      "AiLedgerEntryType": {
        "type": "string",
        "enum": [
          "purchase",
          "allowance",
          "usage",
          "refund",
          "expiry",
          "adjustment"
        ]
      },
      "AiLedgerEntry": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "at": {
            "type": "string",
            "format": "date-time"
          },
          "type": {
            "allOf": [
              {
                "$ref": "#/components/schemas/AiLedgerEntryType"
              }
            ]
          },
          "tokens": {
            "type": "integer",
            "description": "Positive for credits, negative for usage and expiry."
          },
          "userId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "engagementId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "feature": {
            "type": [
              "string",
              "null"
            ]
          },
          "model": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "id",
          "at",
          "type",
          "tokens",
          "userId",
          "engagementId",
          "feature",
          "model"
        ]
      },
      "AiUsage": {
        "type": "object",
        "properties": {
          "groupBy": {
            "allOf": [
              {
                "$ref": "#/components/schemas/AiUsageGroupBy"
              }
            ]
          },
          "groups": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AiUsageGroup"
            }
          },
          "total": {
            "type": "integer"
          },
          "recent": {
            "description": "The 50 most recent ledger entries.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AiLedgerEntry"
            }
          }
        },
        "required": [
          "groupBy",
          "groups",
          "total",
          "recent"
        ]
      },
      "AiPack": {
        "type": "object",
        "properties": {
          "id": {
            "allOf": [
              {
                "$ref": "#/components/schemas/TokenPackId"
              }
            ]
          },
          "name": {
            "type": "string"
          },
          "tokens": {
            "type": "integer"
          },
          "netPence": {
            "type": "integer",
            "description": "Net price in pence."
          },
          "vatPence": {
            "type": "integer",
            "description": "VAT in pence: 0 while Tolvi is not VAT-registered."
          },
          "grossPence": {
            "type": "integer",
            "description": "Net plus VAT, in pence (the net price while Tolvi is not VAT-registered)."
          }
        },
        "required": [
          "id",
          "name",
          "tokens",
          "netPence",
          "vatPence",
          "grossPence"
        ]
      },
      "AiPacks": {
        "type": "object",
        "properties": {
          "version": {
            "type": "string"
          },
          "currency": {
            "type": "string"
          },
          "vatRegistered": {
            "type": "boolean",
            "description": "Whether Tolvi charges VAT on its prices. False: no VAT is charged, so vatPence is 0 and grossPence is the net price."
          },
          "packs": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AiPack"
            }
          }
        },
        "required": [
          "version",
          "currency",
          "vatRegistered",
          "packs"
        ]
      },
      "AiCheckoutRequest": {
        "type": "object",
        "properties": {
          "packId": {
            "allOf": [
              {
                "$ref": "#/components/schemas/TokenPackId"
              }
            ]
          }
        },
        "required": [
          "packId"
        ]
      },
      "AiCheckout": {
        "type": "object",
        "properties": {
          "sessionId": {
            "type": "string"
          },
          "url": {
            "type": "string",
            "format": "uri",
            "description": "Send the browser here (Stripe Checkout)."
          },
          "pack": {
            "$ref": "#/components/schemas/AiPack"
          }
        },
        "required": [
          "sessionId",
          "url",
          "pack"
        ]
      },
      "AskHistoryTurn": {
        "type": "object",
        "properties": {
          "question": {
            "type": "string",
            "maxLength": 4000
          },
          "answer": {
            "type": "string",
            "maxLength": 20000
          }
        },
        "required": [
          "question",
          "answer"
        ]
      },
      "AiRequest": {
        "type": "object",
        "properties": {
          "engagementId": {
            "type": "string",
            "format": "uuid"
          },
          "sectionCode": {
            "type": "string"
          },
          "accountCodes": {
            "maxItems": 200,
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "evidenceId": {
            "type": "string",
            "format": "uuid"
          },
          "question": {
            "type": "string",
            "maxLength": 4000
          },
          "history": {
            "maxItems": 20,
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AskHistoryTurn"
            }
          },
          "estimateOnly": {
            "type": "boolean",
            "description": "Only estimate the cost; nothing is reserved or run."
          }
        },
        "description": "engagementId is required. explain_movements: sectionCode (and optionally accountCodes); review_assistant: optional sectionCode; check_evidence: evidenceId (and optionally the ticked account in accountCodes); ask_tolvi: question (and history).",
        "required": [
          "engagementId"
        ]
      },
      "PriceTableStatus": {
        "type": "string",
        "enum": [
          "draft",
          "confirmed"
        ]
      },
      "PriceTier": {
        "type": "object",
        "properties": {
          "upTo": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Inclusive upper bound (engagements per month); null for the last tier."
          },
          "unitPence": {
            "type": "integer",
            "description": "Pence per engagement, net of VAT."
          }
        },
        "required": [
          "upTo",
          "unitPence"
        ]
      },
      "BillingPlan": {
        "type": "object",
        "properties": {
          "version": {
            "type": "string"
          },
          "status": {
            "allOf": [
              {
                "$ref": "#/components/schemas/PriceTableStatus"
              }
            ]
          },
          "currency": {
            "type": "string"
          },
          "tiers": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PriceTier"
            }
          },
          "trialDays": {
            "type": "integer"
          },
          "freeEngagements": {
            "type": "integer"
          },
          "cancellationDays": {
            "type": "integer"
          },
          "dunningBlockDays": {
            "type": "integer"
          },
          "example100": {
            "type": "integer",
            "description": "What 100 engagements in a month cost, in pence."
          }
        },
        "required": [
          "version",
          "status",
          "currency",
          "tiers",
          "trialDays",
          "freeEngagements",
          "cancellationDays",
          "dunningBlockDays",
          "example100"
        ]
      },
      "TierLine": {
        "type": "object",
        "properties": {
          "from": {
            "type": "integer"
          },
          "to": {
            "type": "integer"
          },
          "count": {
            "type": "integer"
          },
          "unitPence": {
            "type": "integer"
          },
          "amountPence": {
            "type": "integer"
          }
        },
        "required": [
          "from",
          "to",
          "count",
          "unitPence",
          "amountPence"
        ]
      },
      "BillingEstimate": {
        "type": "object",
        "properties": {
          "totalPence": {
            "type": "integer"
          },
          "lines": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TierLine"
            }
          }
        },
        "required": [
          "totalPence",
          "lines"
        ]
      },
      "BillingPeriod": {
        "type": "object",
        "properties": {
          "started": {
            "type": "integer"
          },
          "credited": {
            "type": "integer"
          },
          "free": {
            "type": "integer"
          },
          "billable": {
            "type": "integer"
          },
          "estimate": {
            "$ref": "#/components/schemas/BillingEstimate"
          },
          "from": {
            "type": "string",
            "format": "date-time"
          },
          "to": {
            "type": "string",
            "format": "date-time"
          },
          "nextUnitPence": {
            "type": "integer",
            "description": "Price of the next engagement this month."
          }
        },
        "required": [
          "started",
          "credited",
          "free",
          "billable",
          "estimate",
          "from",
          "to",
          "nextUnitPence"
        ]
      },
      "BillingAccount": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "description": "trialing, trial_ended, or the Stripe subscription status."
          },
          "stripeCustomerId": {
            "type": [
              "string",
              "null"
            ]
          },
          "hasSubscription": {
            "type": "boolean"
          },
          "planId": {
            "type": [
              "string",
              "null"
            ]
          },
          "planInterval": {
            "type": [
              "string",
              "null"
            ]
          },
          "trialEndsAt": {
            "type": "string",
            "format": "date-time"
          },
          "freeEngagements": {
            "type": "integer"
          },
          "freeEngagementsUsed": {
            "type": "integer"
          },
          "dunningSince": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "When an invoice first failed; starting engagements is blocked 14 days after."
          },
          "startBlocked": {
            "type": "boolean"
          },
          "startBlockedReason": {
            "type": [
              "string",
              "null"
            ]
          },
          "billingEmail": {
            "type": [
              "string",
              "null"
            ]
          },
          "vatNumber": {
            "type": [
              "string",
              "null"
            ]
          },
          "plan": {
            "$ref": "#/components/schemas/BillingPlan"
          },
          "period": {
            "$ref": "#/components/schemas/BillingPeriod"
          }
        },
        "required": [
          "status",
          "stripeCustomerId",
          "hasSubscription",
          "planId",
          "planInterval",
          "trialEndsAt",
          "freeEngagements",
          "freeEngagementsUsed",
          "dunningSince",
          "startBlocked",
          "startBlockedReason",
          "billingEmail",
          "vatNumber",
          "plan",
          "period"
        ]
      },
      "PlanCatalogueStatus": {
        "type": "string",
        "enum": [
          "draft",
          "confirmed"
        ]
      },
      "PlanId": {
        "type": "string",
        "enum": [
          "starter",
          "solo",
          "practice",
          "growth",
          "firm",
          "scale",
          "group",
          "group_plus",
          "enterprise"
        ]
      },
      "ApiRateLimitTier": {
        "type": "string",
        "enum": [
          "standard",
          "high",
          "custom"
        ]
      },
      "PlanEntitlements": {
        "type": "object",
        "properties": {
          "sso": {
            "type": "boolean"
          },
          "prioritySupport": {
            "type": "boolean"
          },
          "assistedOnboarding": {
            "type": "boolean"
          },
          "accountManager": {
            "type": "boolean"
          },
          "supportSla": {
            "type": "boolean"
          },
          "multiOfficeReporting": {
            "type": "boolean"
          },
          "apiRateLimitTier": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ApiRateLimitTier"
              }
            ]
          }
        },
        "required": [
          "sso",
          "prioritySupport",
          "assistedOnboarding",
          "accountManager",
          "supportSla",
          "multiOfficeReporting",
          "apiRateLimitTier"
        ]
      },
      "PlanOption": {
        "type": "object",
        "properties": {
          "id": {
            "allOf": [
              {
                "$ref": "#/components/schemas/PlanId"
              }
            ]
          },
          "name": {
            "type": "string"
          },
          "custom": {
            "type": "boolean",
            "description": "Priced per firm (Enterprise)."
          },
          "engagementsPerYear": {
            "type": [
              "integer",
              "null"
            ]
          },
          "monthlyPence": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Pence a month, billed monthly (list price), net of VAT."
          },
          "annualPence": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Pence a year, billed annually upfront (15% off)."
          },
          "aiTokensPerMonth": {
            "type": [
              "integer",
              "null"
            ]
          },
          "overageMonthlyPence": {
            "type": [
              "integer",
              "null"
            ]
          },
          "overageAnnualPence": {
            "type": [
              "integer",
              "null"
            ]
          },
          "entitlements": {
            "$ref": "#/components/schemas/PlanEntitlements"
          }
        },
        "required": [
          "id",
          "name",
          "custom",
          "engagementsPerYear",
          "monthlyPence",
          "annualPence",
          "aiTokensPerMonth",
          "overageMonthlyPence",
          "overageAnnualPence",
          "entitlements"
        ]
      },
      "PlanCatalogue": {
        "type": "object",
        "properties": {
          "version": {
            "type": "string"
          },
          "status": {
            "allOf": [
              {
                "$ref": "#/components/schemas/PlanCatalogueStatus"
              }
            ]
          },
          "currency": {
            "type": "string"
          },
          "annualDiscountBps": {
            "type": "integer"
          },
          "vatRegistered": {
            "type": "boolean",
            "description": "Whether Tolvi charges VAT on these prices. False: no VAT is charged; true: VAT is added at checkout and on invoices."
          },
          "tiers": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PriceTier"
            }
          },
          "plans": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PlanOption"
            }
          }
        },
        "required": [
          "version",
          "status",
          "currency",
          "annualDiscountBps",
          "vatRegistered",
          "tiers",
          "plans"
        ]
      },
      "PlanInterval": {
        "type": "string",
        "enum": [
          "month",
          "year"
        ]
      },
      "TrialStatus": {
        "type": "object",
        "properties": {
          "endsAt": {
            "type": "string",
            "format": "date-time"
          },
          "freeEngagements": {
            "type": "integer"
          },
          "freeEngagementsUsed": {
            "type": "integer"
          },
          "active": {
            "type": "boolean"
          }
        },
        "required": [
          "endsAt",
          "freeEngagements",
          "freeEngagementsUsed",
          "active"
        ]
      },
      "PlanAllowance": {
        "type": "object",
        "properties": {
          "planYearStartsAt": {
            "type": "string",
            "format": "date-time"
          },
          "planYearEndsAt": {
            "type": "string",
            "format": "date-time"
          },
          "total": {
            "type": "integer"
          },
          "used": {
            "type": "integer"
          },
          "remaining": {
            "type": "integer"
          },
          "overage": {
            "type": "integer"
          },
          "overagePence": {
            "type": "integer"
          },
          "overageRatePence": {
            "type": "integer"
          },
          "thresholdsReached": {
            "description": "80 and/or 100 once reached.",
            "type": "array",
            "items": {
              "type": "integer"
            }
          }
        },
        "required": [
          "planYearStartsAt",
          "planYearEndsAt",
          "total",
          "used",
          "remaining",
          "overage",
          "overagePence",
          "overageRatePence",
          "thresholdsReached"
        ]
      },
      "PlanAiTokens": {
        "type": "object",
        "properties": {
          "month": {
            "type": "string",
            "example": "2026-10"
          },
          "included": {
            "type": "integer",
            "description": "Included with the plan this month (no rollover)."
          },
          "used": {
            "type": "integer"
          }
        },
        "required": [
          "month",
          "included",
          "used"
        ]
      },
      "NextInvoice": {
        "type": "object",
        "properties": {
          "date": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "planPence": {
            "type": "integer"
          },
          "overagePence": {
            "type": "integer",
            "description": "Overage not yet invoiced."
          }
        },
        "required": [
          "date",
          "planPence",
          "overagePence"
        ]
      },
      "ScheduledPlanChange": {
        "type": "object",
        "properties": {
          "planId": {
            "allOf": [
              {
                "$ref": "#/components/schemas/PlanId"
              }
            ]
          },
          "interval": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/PlanInterval"
              },
              {
                "type": "null"
              }
            ]
          },
          "effectiveAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          }
        },
        "required": [
          "planId",
          "interval",
          "effectiveAt"
        ]
      },
      "PendingPlanChange": {
        "type": "object",
        "properties": {
          "planId": {
            "allOf": [
              {
                "$ref": "#/components/schemas/PlanId"
              }
            ]
          },
          "interval": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/PlanInterval"
              },
              {
                "type": "null"
              }
            ]
          },
          "paymentUrl": {
            "type": [
              "string",
              "null"
            ],
            "description": "Stripe’s hosted page for paying the invoice."
          }
        },
        "description": "A plan chosen but not yet paid for: nothing is granted until Stripe reports the invoice paid.",
        "required": [
          "planId",
          "interval",
          "paymentUrl"
        ]
      },
      "Subscription": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "description": "trialing, no_plan, or the Stripe subscription status."
          },
          "planId": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/PlanId"
              },
              {
                "type": "null"
              }
            ]
          },
          "planName": {
            "type": [
              "string",
              "null"
            ]
          },
          "interval": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/PlanInterval"
              },
              {
                "type": "null"
              }
            ]
          },
          "pricePence": {
            "type": "integer"
          },
          "mrrPence": {
            "type": "integer"
          },
          "currentPeriodStartsAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "currentPeriodEndsAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "trial": {
            "$ref": "#/components/schemas/TrialStatus"
          },
          "allowance": {
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/PlanAllowance"
              }
            ]
          },
          "aiTokens": {
            "$ref": "#/components/schemas/PlanAiTokens"
          },
          "nextInvoice": {
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/NextInvoice"
              }
            ]
          },
          "entitlements": {
            "$ref": "#/components/schemas/PlanEntitlements"
          },
          "cancelAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "scheduledChange": {
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/ScheduledPlanChange"
              }
            ]
          },
          "pendingChange": {
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/PendingPlanChange"
              }
            ]
          },
          "recommendation": {
            "description": "The plan Tolvi recommends (allowance used up, or overage reaching the next plan’s price).",
            "oneOf": [
              {
                "$ref": "#/components/schemas/PlanId"
              },
              {
                "type": "null"
              }
            ]
          }
        },
        "required": [
          "status",
          "planId",
          "planName",
          "interval",
          "trial",
          "allowance",
          "aiTokens",
          "nextInvoice",
          "entitlements",
          "cancelAt",
          "scheduledChange",
          "recommendation"
        ]
      },
      "ChangePlan": {
        "type": "object",
        "properties": {
          "planId": {
            "allOf": [
              {
                "$ref": "#/components/schemas/PlanId"
              }
            ]
          },
          "interval": {
            "allOf": [
              {
                "$ref": "#/components/schemas/PlanInterval"
              }
            ]
          }
        },
        "required": [
          "planId",
          "interval"
        ]
      },
      "PlanChangeKind": {
        "type": "string",
        "enum": [
          "new",
          "upgrade",
          "downgrade"
        ]
      },
      "PlanChangeEffective": {
        "type": "string",
        "enum": [
          "now",
          "renewal"
        ]
      },
      "PlanChangePreview": {
        "type": "object",
        "properties": {
          "kind": {
            "allOf": [
              {
                "$ref": "#/components/schemas/PlanChangeKind"
              }
            ]
          },
          "effective": {
            "allOf": [
              {
                "$ref": "#/components/schemas/PlanChangeEffective"
              }
            ]
          },
          "effectiveAt": {
            "type": "string",
            "format": "date-time"
          },
          "planId": {
            "allOf": [
              {
                "$ref": "#/components/schemas/PlanId"
              }
            ]
          },
          "interval": {
            "allOf": [
              {
                "$ref": "#/components/schemas/PlanInterval"
              }
            ]
          },
          "pricePence": {
            "type": "integer"
          },
          "prorationPence": {
            "type": "integer",
            "description": "Charged now: the prorated difference for an upgrade (or the first period for a new plan)."
          }
        },
        "required": [
          "kind",
          "effective",
          "effectiveAt",
          "planId",
          "interval",
          "pricePence",
          "prorationPence"
        ]
      },
      "MeetingsPlanId": {
        "type": "string",
        "enum": [
          "meetings_starter",
          "meetings_solo",
          "meetings_team",
          "meetings_practice",
          "meetings_firm"
        ]
      },
      "MeetingsPlan": {
        "type": "object",
        "properties": {
          "id": {
            "allOf": [
              {
                "$ref": "#/components/schemas/MeetingsPlanId"
              }
            ]
          },
          "name": {
            "type": "string"
          },
          "minutesPerMonth": {
            "type": "integer",
            "minimum": 0
          },
          "monthlyPence": {
            "type": "integer",
            "minimum": 0,
            "description": "Pence, excluding VAT."
          },
          "annualPence": {
            "type": "integer",
            "minimum": 0,
            "description": "Pence, excluding VAT (15% off 12 months)."
          }
        },
        "description": "A Meetings tier: recorded minutes a month, pooled across the firm.",
        "required": [
          "id",
          "name",
          "minutesPerMonth",
          "monthlyPence",
          "annualPence"
        ]
      },
      "FirmProductStatus": {
        "type": "string",
        "enum": [
          "active",
          "trial",
          "suspended"
        ],
        "description": "Null: the firm doesn’t have Meetings."
      },
      "MeetingsScheduledChange": {
        "type": "object",
        "properties": {
          "planId": {
            "description": "Null: Meetings ends.",
            "oneOf": [
              {
                "$ref": "#/components/schemas/MeetingsPlanId"
              },
              {
                "type": "null"
              }
            ]
          },
          "effectiveAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "The end of the current billing period."
          }
        },
        "required": [
          "planId",
          "effectiveAt"
        ]
      },
      "MeetingsUsageThisMonth": {
        "type": "object",
        "properties": {
          "month": {
            "type": "string",
            "example": "2026-10"
          },
          "minutesUsed": {
            "type": "integer",
            "minimum": 0
          },
          "allowance": {
            "type": "integer",
            "minimum": 0
          },
          "remaining": {
            "type": "integer",
            "minimum": 0
          },
          "overageMinutes": {
            "type": "integer",
            "minimum": 0
          },
          "overagePence": {
            "type": "integer",
            "minimum": 0,
            "description": "Pence, excluding VAT; billed in arrears on a paid plan."
          },
          "thresholdsReached": {
            "type": "array",
            "items": {
              "type": "number"
            }
          }
        },
        "required": [
          "month",
          "minutesUsed",
          "allowance",
          "remaining",
          "overageMinutes",
          "overagePence",
          "thresholdsReached"
        ]
      },
      "MeetingsBilling": {
        "type": "object",
        "properties": {
          "catalogueVersion": {
            "type": "string"
          },
          "vatRegistered": {
            "type": "boolean"
          },
          "overagePencePerMinute": {
            "type": "integer",
            "minimum": 0
          },
          "trialMinutes": {
            "type": "integer",
            "minimum": 0
          },
          "plans": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/MeetingsPlan"
            }
          },
          "subscribed": {
            "type": "boolean",
            "description": "The firm has a Tolvi subscription that Meetings is (or can be) part of. If not, Meetings is bought on its own through Checkout."
          },
          "standalone": {
            "type": "boolean",
            "description": "Meetings is the firm’s only Tolvi subscription."
          },
          "annualDiscountBps": {
            "type": "integer",
            "minimum": 0,
            "description": "Annual discount in basis points (1500 = 15%)."
          },
          "pendingCheckoutUrl": {
            "type": [
              "string",
              "null"
            ],
            "format": "uri",
            "description": "A Meetings Checkout started but not finished: send the browser here."
          },
          "interval": {
            "description": "Meetings bills at the subscription’s interval.",
            "oneOf": [
              {
                "$ref": "#/components/schemas/PlanInterval"
              },
              {
                "type": "null"
              }
            ]
          },
          "status": {
            "description": "Null: the firm doesn’t have Meetings.",
            "oneOf": [
              {
                "$ref": "#/components/schemas/FirmProductStatus"
              },
              {
                "type": "null"
              }
            ]
          },
          "planId": {
            "description": "Null on a trial.",
            "oneOf": [
              {
                "$ref": "#/components/schemas/MeetingsPlanId"
              },
              {
                "type": "null"
              }
            ]
          },
          "planName": {
            "type": [
              "string",
              "null"
            ]
          },
          "scheduledChange": {
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/MeetingsScheduledChange"
              }
            ]
          },
          "usage": {
            "$ref": "#/components/schemas/MeetingsUsageThisMonth"
          },
          "recommendation": {
            "description": "The overage has reached the next tier’s price.",
            "oneOf": [
              {
                "$ref": "#/components/schemas/MeetingsPlanId"
              },
              {
                "type": "null"
              }
            ]
          }
        },
        "description": "The Meetings tiers, the firm’s Meetings plan and this month’s minutes.",
        "required": [
          "catalogueVersion",
          "vatRegistered",
          "overagePencePerMinute",
          "trialMinutes",
          "plans",
          "subscribed",
          "standalone",
          "annualDiscountBps",
          "pendingCheckoutUrl",
          "interval",
          "status",
          "planId",
          "planName",
          "scheduledChange",
          "usage",
          "recommendation"
        ]
      },
      "ChangeMeetingsPlan": {
        "type": "object",
        "properties": {
          "planId": {
            "description": "Null cancels Meetings at the end of the billing period.",
            "oneOf": [
              {
                "$ref": "#/components/schemas/MeetingsPlanId"
              },
              {
                "type": "null"
              }
            ]
          },
          "interval": {
            "description": "Only when buying Meetings on its own (no Tolvi subscription yet). Default month.",
            "allOf": [
              {
                "$ref": "#/components/schemas/PlanInterval"
              }
            ]
          }
        },
        "required": [
          "planId"
        ]
      },
      "BillingPeriodSummary": {
        "type": "object",
        "properties": {
          "started": {
            "type": "integer"
          },
          "credited": {
            "type": "integer"
          },
          "free": {
            "type": "integer"
          },
          "billable": {
            "type": "integer"
          },
          "estimate": {
            "$ref": "#/components/schemas/BillingEstimate"
          }
        },
        "required": [
          "started",
          "credited",
          "free",
          "billable",
          "estimate"
        ]
      },
      "BillableKind": {
        "type": "string",
        "enum": [
          "started",
          "credit"
        ]
      },
      "BillableSource": {
        "type": "string",
        "enum": [
          "web",
          "api",
          "mcp",
          "bulk"
        ]
      },
      "BillableEvent": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "kind": {
            "allOf": [
              {
                "$ref": "#/components/schemas/BillableKind"
              }
            ]
          },
          "engagementId": {
            "type": "string",
            "format": "uuid"
          },
          "clientId": {
            "type": "string",
            "format": "uuid"
          },
          "clientName": {
            "type": "string"
          },
          "periodEnd": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "source": {
            "allOf": [
              {
                "$ref": "#/components/schemas/BillableSource"
              }
            ]
          },
          "startedBy": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "free": {
            "type": "boolean",
            "description": "One of the trial’s free engagements."
          },
          "at": {
            "type": "string",
            "format": "date-time"
          },
          "reportableAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "When the cancellation window closes and it is reported to Stripe."
          },
          "reportedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "kind",
          "engagementId",
          "clientId",
          "clientName",
          "periodEnd",
          "source",
          "startedBy",
          "free",
          "at",
          "reportableAt",
          "reportedAt"
        ]
      },
      "BillingUsage": {
        "type": "object",
        "properties": {
          "from": {
            "type": "string",
            "format": "date-time"
          },
          "to": {
            "type": "string",
            "format": "date-time"
          },
          "summary": {
            "$ref": "#/components/schemas/BillingPeriodSummary"
          },
          "events": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BillableEvent"
            }
          }
        },
        "required": [
          "from",
          "to",
          "summary",
          "events"
        ]
      },
      "Invoice": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "stripeInvoiceId": {
            "type": "string"
          },
          "number": {
            "type": [
              "string",
              "null"
            ]
          },
          "status": {
            "type": "string"
          },
          "amountDuePence": {
            "type": "integer"
          },
          "amountPaidPence": {
            "type": "integer"
          },
          "currency": {
            "type": "string"
          },
          "hostedInvoiceUrl": {
            "type": [
              "string",
              "null"
            ]
          },
          "invoicePdf": {
            "type": [
              "string",
              "null"
            ]
          },
          "periodStart": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "periodEnd": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "stripeInvoiceId",
          "number",
          "status",
          "amountDuePence",
          "amountPaidPence",
          "currency",
          "hostedInvoiceUrl",
          "invoicePdf",
          "periodStart",
          "periodEnd",
          "createdAt"
        ]
      },
      "BillingSetup": {
        "type": "object",
        "properties": {
          "billingEmail": {
            "type": "string",
            "format": "email"
          },
          "vatNumber": {
            "type": "string",
            "example": "GB123456789"
          }
        }
      },
      "PortalSession": {
        "type": "object",
        "properties": {
          "url": {
            "type": "string",
            "format": "uri"
          }
        },
        "required": [
          "url"
        ]
      },
      "StartBlockReason": {
        "type": "string",
        "enum": [
          "dunning",
          "plan_required",
          "trial_ended"
        ],
        "description": "Why starting is blocked: an invoice unpaid for 14 days, the trial’s free engagements used, or the trial over without a plan. Null when it isn’t."
      },
      "StartAllowance": {
        "type": "object",
        "properties": {
          "used": {
            "type": "integer",
            "minimum": 0
          },
          "total": {
            "type": "integer",
            "minimum": 0
          }
        },
        "description": "Engagements used this plan year and the plan’s yearly allowance. Counts only.",
        "required": [
          "used",
          "total"
        ]
      },
      "EngagementStartStatus": {
        "type": "object",
        "properties": {
          "canStart": {
            "type": "boolean",
            "description": "False when starting an engagement would fail with 402."
          },
          "reason": {
            "description": "Why starting is blocked: an invoice unpaid for 14 days, the trial’s free engagements used, or the trial over without a plan. Null when it isn’t.",
            "oneOf": [
              {
                "$ref": "#/components/schemas/StartBlockReason"
              },
              {
                "type": "null"
              }
            ]
          },
          "message": {
            "type": [
              "string",
              "null"
            ],
            "description": "The same message a blocked start returns with its 402."
          },
          "startsLeft": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 0,
            "description": "How many more engagements can start before the gate closes (the trial’s free ones left); null when there is no limit."
          },
          "allowance": {
            "description": "The plan year’s engagement allowance, as counts: how many have been used and how many the plan includes. Null on the trial, an Enterprise plan or no plan. Going over never stops work.",
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/StartAllowance"
              }
            ]
          }
        },
        "description": "Whether the firm can start engagements now. Readable by anyone who starts engagements; no prices, plan or invoices.",
        "required": [
          "canStart",
          "reason",
          "message",
          "startsLeft"
        ]
      },
      "BooksPriceStatus": {
        "type": "string",
        "enum": [
          "placeholder",
          "draft",
          "confirmed"
        ],
        "description": "placeholder: prices still to be confirmed."
      },
      "BooksPlanId": {
        "type": "string",
        "enum": [
          "books_sole_trader",
          "books_limited_company",
          "books_vat_registered"
        ]
      },
      "BooksPlan": {
        "type": "object",
        "properties": {
          "id": {
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksPlanId"
              }
            ]
          },
          "name": {
            "type": "string"
          },
          "who": {
            "type": "string",
            "description": "Who the plan is for, in plain English."
          },
          "monthlyPence": {
            "type": "integer",
            "minimum": 0
          },
          "annualPence": {
            "type": "integer",
            "minimum": 0,
            "description": "12 × monthly less the annual discount, in whole pounds."
          },
          "wholesaleMonthlyPence": {
            "type": "integer",
            "minimum": 0,
            "description": "What a practice pays per client a month."
          },
          "aiFairUsePerMonth": {
            "type": "integer",
            "minimum": 0,
            "description": "AI suggestions a month within fair use. Past it, nothing stops and nothing is charged."
          },
          "vatReturns": {
            "type": "boolean",
            "description": "MTD VAT returns are included."
          },
          "includes": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        },
        "description": "A Tolvi Books tier. Prices are pence, excluding VAT.",
        "required": [
          "id",
          "name",
          "who",
          "monthlyPence",
          "annualPence",
          "wholesaleMonthlyPence",
          "aiFairUsePerMonth",
          "vatReturns",
          "includes"
        ]
      },
      "BooksPaidBy": {
        "type": "string",
        "enum": [
          "business",
          "practice",
          "trial",
          "included",
          "none"
        ]
      },
      "BooksPayingPractice": {
        "type": "object",
        "properties": {
          "linkId": {
            "type": "string",
            "format": "uuid"
          },
          "firmName": {
            "type": "string"
          }
        },
        "required": [
          "linkId",
          "firmName"
        ]
      },
      "BooksScheduledChange": {
        "type": "object",
        "properties": {
          "planId": {
            "description": "Null: Tolvi Books ends.",
            "oneOf": [
              {
                "$ref": "#/components/schemas/BooksPlanId"
              },
              {
                "type": "null"
              }
            ]
          },
          "interval": {
            "description": "Moves to this billing period; null keeps the current one.",
            "oneOf": [
              {
                "$ref": "#/components/schemas/PlanInterval"
              },
              {
                "type": "null"
              }
            ]
          },
          "effectiveAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          }
        },
        "required": [
          "planId",
          "interval",
          "effectiveAt"
        ]
      },
      "BooksFairUse": {
        "type": "object",
        "properties": {
          "month": {
            "type": "string",
            "example": "2026-10"
          },
          "allowance": {
            "type": "integer",
            "minimum": 0
          },
          "used": {
            "type": "integer",
            "minimum": 0
          },
          "remaining": {
            "type": "integer",
            "minimum": 0
          },
          "over": {
            "type": "boolean"
          }
        },
        "description": "AI suggestions this calendar month (UTC) against the fair-use allowance.",
        "required": [
          "month",
          "allowance",
          "used",
          "remaining",
          "over"
        ]
      },
      "BooksBilling": {
        "type": "object",
        "properties": {
          "catalogueVersion": {
            "type": "string"
          },
          "priceStatus": {
            "description": "placeholder: prices still to be confirmed.",
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksPriceStatus"
              }
            ]
          },
          "vatRegistered": {
            "type": "boolean",
            "description": "Tolvi charges VAT on top of these prices."
          },
          "annualDiscountBps": {
            "type": "integer",
            "minimum": 0
          },
          "trialDays": {
            "type": "integer",
            "minimum": 0
          },
          "plans": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BooksPlan"
            }
          },
          "requiredPlanId": {
            "description": "The tier this business needs (from its type and VAT registration); it may choose a higher one.",
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksPlanId"
              }
            ]
          },
          "status": {
            "description": "suspended: read-only (an ended trial, or no plan). Reading and exporting are never blocked.",
            "allOf": [
              {
                "$ref": "#/components/schemas/FirmProductStatus"
              }
            ]
          },
          "paidBy": {
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksPaidBy"
              }
            ]
          },
          "practice": {
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksPayingPractice"
              }
            ]
          },
          "planId": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/BooksPlanId"
              },
              {
                "type": "null"
              }
            ]
          },
          "planName": {
            "type": [
              "string",
              "null"
            ]
          },
          "interval": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/PlanInterval"
              },
              {
                "type": "null"
              }
            ]
          },
          "trialEndsAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "currentPeriodEndsAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "cancelAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "scheduledChange": {
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksScheduledChange"
              }
            ]
          },
          "pendingCheckoutUrl": {
            "type": [
              "string",
              "null"
            ],
            "format": "uri",
            "description": "A Checkout started but not finished: send the browser here."
          },
          "fairUse": {
            "$ref": "#/components/schemas/BooksFairUse"
          },
          "endedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "When the plan or trial ended. Set while read-only; cleared on choosing a plan."
          },
          "dataDeletesOn": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "When the books are due to be deleted: 6 years after endedAt."
          },
          "dataDeletedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "When the books were deleted, 6 years after the plan ended."
          }
        },
        "description": "A business’s Tolvi Books plan, how it is paid for, and the tiers.",
        "required": [
          "catalogueVersion",
          "priceStatus",
          "vatRegistered",
          "annualDiscountBps",
          "trialDays",
          "plans",
          "requiredPlanId",
          "status",
          "paidBy",
          "practice",
          "planId",
          "planName",
          "interval",
          "trialEndsAt",
          "currentPeriodEndsAt",
          "cancelAt",
          "scheduledChange",
          "pendingCheckoutUrl",
          "fairUse",
          "endedAt",
          "dataDeletesOn",
          "dataDeletedAt"
        ]
      },
      "ChangeBooksPlan": {
        "type": "object",
        "properties": {
          "planId": {
            "description": "Null cancels at the end of the billing period.",
            "oneOf": [
              {
                "$ref": "#/components/schemas/BooksPlanId"
              },
              {
                "type": "null"
              }
            ]
          },
          "interval": {
            "description": "Buying a first plan (default month), or moving the current plan: to year applies now, prorated; to month at the end of the billing period.",
            "allOf": [
              {
                "$ref": "#/components/schemas/PlanInterval"
              }
            ]
          }
        },
        "required": [
          "planId"
        ]
      },
      "BooksPortalSession": {
        "type": "object",
        "properties": {
          "url": {
            "type": "string",
            "format": "uri"
          }
        },
        "required": [
          "url"
        ]
      },
      "PracticeBooksPlan": {
        "type": "object",
        "properties": {
          "id": {
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksPlanId"
              }
            ]
          },
          "name": {
            "type": "string"
          },
          "who": {
            "type": "string"
          },
          "wholesaleMonthlyPence": {
            "type": "integer",
            "minimum": 0
          }
        },
        "required": [
          "id",
          "name",
          "who",
          "wholesaleMonthlyPence"
        ]
      },
      "LinkBilledBy": {
        "type": "string",
        "enum": [
          "business",
          "firm"
        ],
        "description": "Who the business said should pay, on its link."
      },
      "PracticeBooksBillingStatus": {
        "type": "string",
        "enum": [
          "pending",
          "active"
        ],
        "description": "pending: waiting for the prorated invoice to be paid."
      },
      "PracticeBooksClientBilling": {
        "type": "object",
        "properties": {
          "status": {
            "description": "pending: waiting for the prorated invoice to be paid.",
            "allOf": [
              {
                "$ref": "#/components/schemas/PracticeBooksBillingStatus"
              }
            ]
          },
          "since": {
            "type": "string",
            "format": "date-time"
          },
          "paymentUrl": {
            "type": [
              "string",
              "null"
            ],
            "format": "uri"
          }
        },
        "required": [
          "status",
          "since",
          "paymentUrl"
        ]
      },
      "PracticeBooksClient": {
        "type": "object",
        "properties": {
          "linkId": {
            "type": "string",
            "format": "uuid"
          },
          "businessId": {
            "type": "string",
            "format": "uuid"
          },
          "businessName": {
            "type": "string"
          },
          "clientPrefers": {
            "description": "Who the business said should pay, on its link.",
            "allOf": [
              {
                "$ref": "#/components/schemas/LinkBilledBy"
              }
            ]
          },
          "planId": {
            "description": "The tier the business needs.",
            "oneOf": [
              {
                "$ref": "#/components/schemas/BooksPlanId"
              },
              {
                "type": "null"
              }
            ]
          },
          "planName": {
            "type": [
              "string",
              "null"
            ]
          },
          "wholesaleMonthlyPence": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 0
          },
          "booksStatus": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/FirmProductStatus"
              },
              {
                "type": "null"
              }
            ]
          },
          "trialEndsAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "paysItself": {
            "type": "boolean",
            "description": "The business pays for its own plan."
          },
          "consentText": {
            "type": [
              "string",
              "null"
            ],
            "description": "What a firm admin agrees to before paying for this client."
          },
          "billing": {
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/PracticeBooksClientBilling"
              }
            ]
          }
        },
        "required": [
          "linkId",
          "businessId",
          "businessName",
          "clientPrefers",
          "planId",
          "planName",
          "wholesaleMonthlyPence",
          "booksStatus",
          "trialEndsAt",
          "paysItself",
          "consentText",
          "billing"
        ]
      },
      "PracticeBooksBilling": {
        "type": "object",
        "properties": {
          "catalogueVersion": {
            "type": "string"
          },
          "priceStatus": {
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksPriceStatus"
              }
            ]
          },
          "vatRegistered": {
            "type": "boolean"
          },
          "consentVersion": {
            "type": "string"
          },
          "plans": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PracticeBooksPlan"
            }
          },
          "subscribed": {
            "type": "boolean",
            "description": "The firm has a Tolvi subscription to add clients to. Without one, paying for a client starts a Stripe Checkout for Tolvi Books alone."
          },
          "pendingCheckoutUrl": {
            "type": [
              "string",
              "null"
            ],
            "format": "uri",
            "description": "A Checkout for clients’ Tolvi Books started but not finished: send the browser here."
          },
          "monthlyTotalPence": {
            "type": "integer",
            "minimum": 0
          },
          "clients": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PracticeBooksClient"
            }
          }
        },
        "description": "The firm’s linked clients and whose Tolvi Books it pays for, at the wholesale price.",
        "required": [
          "catalogueVersion",
          "priceStatus",
          "vatRegistered",
          "consentVersion",
          "plans",
          "subscribed",
          "pendingCheckoutUrl",
          "monthlyTotalPence",
          "clients"
        ]
      },
      "PayForClientBooks": {
        "type": "object",
        "properties": {
          "agree": {
            "type": "boolean",
            "description": "Must be true: the firm admin agrees to the client’s consentText."
          }
        },
        "required": [
          "agree"
        ]
      },
      "StopPayingForClientBooks": {
        "type": "object",
        "properties": {
          "reason": {
            "type": "string",
            "maxLength": 500
          }
        }
      },
      "EmailPreferences": {
        "type": "object",
        "properties": {
          "notifications": {
            "type": "boolean",
            "description": "Immediate emails for notifications the firm sends by email (mentions, review hand-offs). Billing problems are always emailed to admins."
          },
          "digest": {
            "type": "boolean",
            "description": "The daily summary of notifications the firm puts in the digest."
          },
          "reminders": {
            "type": "boolean",
            "description": "Deadline reminder emails. The in-app reminder still arrives."
          },
          "trial": {
            "type": "boolean",
            "description": "Tips during a Tolvi trial (getting started, halfway). Notices about the trial ending always arrive."
          }
        },
        "description": "Which emails you get from this firm. The firm’s notification settings decide what can be emailed at all.",
        "required": [
          "notifications",
          "digest",
          "reminders",
          "trial"
        ]
      },
      "EmailPreferencesPatch": {
        "type": "object",
        "properties": {
          "notifications": {
            "type": "boolean"
          },
          "digest": {
            "type": "boolean"
          },
          "reminders": {
            "type": "boolean"
          },
          "trial": {
            "type": "boolean"
          }
        }
      },
      "EmailLinkScope": {
        "type": "string",
        "enum": [
          "notifications",
          "digest",
          "reminders",
          "trial",
          "all"
        ],
        "description": "What this link may change."
      },
      "EmailLinkPreferences": {
        "type": "object",
        "properties": {
          "notifications": {
            "type": "boolean",
            "description": "Immediate emails for notifications the firm sends by email (mentions, review hand-offs). Billing problems are always emailed to admins."
          },
          "digest": {
            "type": "boolean",
            "description": "The daily summary of notifications the firm puts in the digest."
          },
          "reminders": {
            "type": "boolean",
            "description": "Deadline reminder emails. The in-app reminder still arrives."
          },
          "trial": {
            "type": "boolean",
            "description": "Tips during a Tolvi trial (getting started, halfway). Notices about the trial ending always arrive."
          },
          "firmName": {
            "type": "string"
          },
          "email": {
            "type": "string",
            "format": "email"
          },
          "scope": {
            "description": "What this link may change.",
            "allOf": [
              {
                "$ref": "#/components/schemas/EmailLinkScope"
              }
            ]
          }
        },
        "description": "Preferences opened from the link in an email.",
        "required": [
          "notifications",
          "digest",
          "reminders",
          "trial",
          "firmName",
          "email",
          "scope"
        ]
      },
      "WebhookEventType": {
        "type": "string",
        "enum": [
          "engagement.stage_changed",
          "section.signed_off",
          "review_point.raised",
          "review_point.cleared",
          "tb.imported",
          "sync.change_detected",
          "self_assessment.filed",
          "accounts.approved",
          "corporation_tax.filed"
        ]
      },
      "WebhookEventTypeInfo": {
        "type": "object",
        "properties": {
          "type": {
            "allOf": [
              {
                "$ref": "#/components/schemas/WebhookEventType"
              }
            ]
          },
          "description": {
            "type": "string"
          }
        },
        "required": [
          "type",
          "description"
        ]
      },
      "WebhookSubscriptionStatus": {
        "type": "string",
        "enum": [
          "active",
          "disabled"
        ]
      },
      "WebhookSubscription": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "url": {
            "type": "string",
            "format": "uri",
            "example": "https://hooks.example.co.uk/tolvi"
          },
          "description": {
            "type": [
              "string",
              "null"
            ]
          },
          "eventTypes": {
            "type": "array",
            "minItems": 1,
            "items": {
              "$ref": "#/components/schemas/WebhookEventType"
            }
          },
          "status": {
            "allOf": [
              {
                "$ref": "#/components/schemas/WebhookSubscriptionStatus"
              }
            ]
          },
          "disabledReason": {
            "type": [
              "string",
              "null"
            ],
            "description": "Why it was disabled: by hand, or automatically after repeated failed deliveries."
          },
          "disabledAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "consecutiveFailures": {
            "type": "integer",
            "minimum": 0,
            "description": "Failed attempts in a row. Reaching the limit disables the subscription and tells the firm’s admins."
          },
          "secretPrefix": {
            "type": "string",
            "example": "whsec_AbC1",
            "description": "First characters of the signing secret."
          },
          "createdBy": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "url",
          "description",
          "eventTypes",
          "status",
          "disabledReason",
          "disabledAt",
          "consecutiveFailures",
          "secretPrefix",
          "createdBy",
          "createdAt",
          "updatedAt"
        ]
      },
      "CreateWebhookSubscription": {
        "type": "object",
        "properties": {
          "url": {
            "type": "string",
            "format": "uri",
            "maxLength": 2048,
            "description": "An https URL on a public host. Private, loopback and link-local addresses are refused."
          },
          "eventTypes": {
            "type": "array",
            "minItems": 1,
            "items": {
              "$ref": "#/components/schemas/WebhookEventType"
            }
          },
          "description": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 200
          }
        },
        "required": [
          "url",
          "eventTypes"
        ]
      },
      "CreatedWebhookSubscription": {
        "type": "object",
        "properties": {
          "subscription": {
            "$ref": "#/components/schemas/WebhookSubscription"
          },
          "secret": {
            "type": "string",
            "example": "whsec_…"
          }
        },
        "description": "The signing secret is shown only once. Use it to verify the Tolvi-Signature header.",
        "required": [
          "subscription",
          "secret"
        ]
      },
      "UpdateWebhookSubscription": {
        "type": "object",
        "properties": {
          "url": {
            "type": "string",
            "format": "uri",
            "maxLength": 2048
          },
          "eventTypes": {
            "type": "array",
            "minItems": 1,
            "items": {
              "$ref": "#/components/schemas/WebhookEventType"
            }
          },
          "description": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 200
          },
          "status": {
            "description": "`active` re-enables a disabled subscription and resets its failure count.",
            "allOf": [
              {
                "$ref": "#/components/schemas/WebhookSubscriptionStatus"
              }
            ]
          }
        }
      },
      "TestWebhookEndpoint": {
        "type": "object",
        "properties": {
          "url": {
            "type": "string",
            "format": "uri",
            "maxLength": 2048,
            "description": "An https URL on a public host, checked exactly as a subscription’s is."
          }
        },
        "required": [
          "url"
        ]
      },
      "WebhookEndpointTest": {
        "type": "object",
        "properties": {
          "ok": {
            "type": "boolean",
            "description": "The endpoint answered 2xx within 10 seconds."
          },
          "status": {
            "type": [
              "integer",
              "null"
            ],
            "description": "The HTTP status it answered with; null when nothing came back."
          },
          "error": {
            "type": [
              "string",
              "null"
            ],
            "description": "Why it failed, in words: a refused address, a timeout, no answer."
          },
          "durationMs": {
            "type": "integer",
            "description": "How long it took, in milliseconds."
          }
        },
        "description": "What happened when Tolvi sent a test event (type ping) to an endpoint. Nothing is stored.",
        "required": [
          "ok",
          "status",
          "error",
          "durationMs"
        ]
      },
      "WebhookDeliveryStatus": {
        "type": "string",
        "enum": [
          "pending",
          "succeeded",
          "failed"
        ]
      },
      "WebhookDelivery": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "Sent as Tolvi-Delivery-Id."
          },
          "subscriptionId": {
            "type": "string",
            "format": "uuid"
          },
          "eventId": {
            "type": "string",
            "format": "uuid",
            "description": "Sent as Tolvi-Event-Id and as `id` in the body: the same on retries and replays."
          },
          "eventType": {
            "allOf": [
              {
                "$ref": "#/components/schemas/WebhookEventType"
              }
            ]
          },
          "status": {
            "allOf": [
              {
                "$ref": "#/components/schemas/WebhookDeliveryStatus"
              }
            ]
          },
          "attempts": {
            "type": "integer",
            "minimum": 0
          },
          "nextAttemptAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "When the next attempt is due (pending deliveries only)."
          },
          "lastAttemptAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "responseStatus": {
            "type": [
              "integer",
              "null"
            ]
          },
          "error": {
            "type": [
              "string",
              "null"
            ]
          },
          "replayOf": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid",
            "description": "The delivery this one replays."
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "subscriptionId",
          "eventId",
          "eventType",
          "status",
          "attempts",
          "nextAttemptAt",
          "lastAttemptAt",
          "responseStatus",
          "error",
          "replayOf",
          "createdAt"
        ]
      },
      "WebhookDeliveryPage": {
        "type": "object",
        "properties": {
          "rows": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/WebhookDelivery"
            }
          },
          "nextCursor": {
            "type": [
              "string",
              "null"
            ],
            "description": "Opaque cursor for the next page (pass as `cursor`); null on the last page."
          },
          "pageSize": {
            "type": "integer",
            "minimum": 1,
            "maximum": 100,
            "description": "The page size that was used."
          }
        },
        "required": [
          "rows",
          "nextCursor",
          "pageSize"
        ]
      },
      "WebhookDeliveryAttempt": {
        "type": "object",
        "properties": {
          "attempt": {
            "type": "integer",
            "minimum": 1
          },
          "at": {
            "type": "string",
            "format": "date-time"
          },
          "responseStatus": {
            "type": [
              "integer",
              "null"
            ],
            "description": "HTTP status, or null when no response came back."
          },
          "responseBody": {
            "type": [
              "string",
              "null"
            ],
            "description": "First 1 KB of the response body."
          },
          "error": {
            "type": [
              "string",
              "null"
            ],
            "description": "Network error, timeout or refused address."
          },
          "durationMs": {
            "type": "integer",
            "minimum": 0
          }
        },
        "required": [
          "attempt",
          "at",
          "responseStatus",
          "responseBody",
          "error",
          "durationMs"
        ]
      },
      "WebhookDeliveryDetail": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "Sent as Tolvi-Delivery-Id."
          },
          "subscriptionId": {
            "type": "string",
            "format": "uuid"
          },
          "eventId": {
            "type": "string",
            "format": "uuid",
            "description": "Sent as Tolvi-Event-Id and as `id` in the body: the same on retries and replays."
          },
          "eventType": {
            "allOf": [
              {
                "$ref": "#/components/schemas/WebhookEventType"
              }
            ]
          },
          "status": {
            "allOf": [
              {
                "$ref": "#/components/schemas/WebhookDeliveryStatus"
              }
            ]
          },
          "attempts": {
            "type": "integer",
            "minimum": 0
          },
          "nextAttemptAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "When the next attempt is due (pending deliveries only)."
          },
          "lastAttemptAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "responseStatus": {
            "type": [
              "integer",
              "null"
            ]
          },
          "error": {
            "type": [
              "string",
              "null"
            ]
          },
          "replayOf": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid",
            "description": "The delivery this one replays."
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "payload": {
            "type": "string",
            "description": "The exact JSON body that is signed and sent."
          },
          "attemptLog": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/WebhookDeliveryAttempt"
            }
          }
        },
        "required": [
          "id",
          "subscriptionId",
          "eventId",
          "eventType",
          "status",
          "attempts",
          "nextAttemptAt",
          "lastAttemptAt",
          "responseStatus",
          "error",
          "replayOf",
          "createdAt",
          "payload",
          "attemptLog"
        ]
      },
      "TourProduct": {
        "type": "string",
        "enum": [
          "working_papers",
          "meetings",
          "admin"
        ]
      },
      "TourStatus": {
        "type": "string",
        "enum": [
          "not_started",
          "in_progress",
          "skipped",
          "completed"
        ],
        "description": "not_started: never opened (the web app starts it). in_progress: open, or left part-way. skipped: closed early; it can be resumed from Help. completed: finished."
      },
      "TourState": {
        "type": "object",
        "properties": {
          "status": {
            "description": "not_started: never opened (the web app starts it). in_progress: open, or left part-way. skipped: closed early; it can be resumed from Help. completed: finished.",
            "allOf": [
              {
                "$ref": "#/components/schemas/TourStatus"
              }
            ]
          },
          "stepId": {
            "type": [
              "string",
              "null"
            ],
            "example": "add-client",
            "description": "The step to resume at; null for the first step."
          },
          "checklistHidden": {
            "type": "boolean",
            "description": "The Getting started checklist on the Work page is hidden."
          },
          "updatedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "Null until you first open the tour or hide the checklist."
          }
        },
        "description": "Your progress through the welcome tour in this firm, and whether you have hidden the Getting started checklist.",
        "required": [
          "status",
          "stepId",
          "checklistHidden",
          "updatedAt"
        ]
      },
      "TourStatePatch": {
        "type": "object",
        "properties": {
          "status": {
            "description": "not_started: never opened (the web app starts it). in_progress: open, or left part-way. skipped: closed early; it can be resumed from Help. completed: finished.",
            "allOf": [
              {
                "$ref": "#/components/schemas/TourStatus"
              }
            ]
          },
          "stepId": {
            "type": [
              "string",
              "null"
            ],
            "pattern": "^[a-z][a-z0-9-]{0,39}$",
            "maxLength": 40
          },
          "checklistHidden": {
            "type": "boolean"
          }
        },
        "description": "Only the fields sent are changed."
      },
      "SearchGroup": {
        "type": "string",
        "enum": [
          "clients",
          "engagements",
          "sections",
          "meetings",
          "people",
          "taxReturns",
          "companyTaxReturns",
          "accountsSets"
        ],
        "description": "The groups searched for this caller."
      },
      "SearchClient": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "entityType": {
            "allOf": [
              {
                "$ref": "#/components/schemas/EntityType"
              }
            ]
          },
          "companyNumber": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "id",
          "name",
          "entityType",
          "companyNumber"
        ]
      },
      "SearchEngagement": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "clientId": {
            "type": "string",
            "format": "uuid"
          },
          "clientName": {
            "type": "string"
          },
          "periodEnd": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "stageName": {
            "type": "string",
            "description": "The current workflow stage, e.g. \"Preparation\"."
          },
          "status": {
            "allOf": [
              {
                "$ref": "#/components/schemas/EngagementStatus"
              }
            ]
          }
        },
        "required": [
          "id",
          "clientId",
          "clientName",
          "periodEnd",
          "stageName",
          "status"
        ]
      },
      "SearchSection": {
        "type": "object",
        "properties": {
          "engagementId": {
            "type": "string",
            "format": "uuid"
          },
          "code": {
            "type": "string",
            "example": "F"
          },
          "name": {
            "type": "string",
            "example": "Bank & cash"
          }
        },
        "description": "A section of the engagement named in `engagementId`.",
        "required": [
          "engagementId",
          "code",
          "name"
        ]
      },
      "MeetingStatus": {
        "type": "string",
        "enum": [
          "scheduling",
          "scheduled",
          "joining",
          "waiting_room",
          "in_call",
          "recording",
          "processing",
          "ready",
          "failed",
          "cancelled"
        ]
      },
      "SearchMeeting": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "title": {
            "type": "string"
          },
          "clientName": {
            "type": [
              "string",
              "null"
            ]
          },
          "joinAt": {
            "type": "string",
            "format": "date-time"
          },
          "status": {
            "allOf": [
              {
                "$ref": "#/components/schemas/MeetingStatus"
              }
            ]
          }
        },
        "required": [
          "id",
          "title",
          "clientName",
          "joinAt",
          "status"
        ]
      },
      "SearchPerson": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "email": {
            "type": "string"
          },
          "staffRole": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/StaffRole"
              },
              {
                "type": "null"
              }
            ]
          }
        },
        "required": [
          "id",
          "name",
          "email",
          "staffRole"
        ]
      },
      "SearchWorkItem": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "clientId": {
            "type": "string",
            "format": "uuid"
          },
          "clientName": {
            "type": "string"
          },
          "periodLabel": {
            "type": "string",
            "example": "2025/26"
          },
          "status": {
            "type": "string",
            "description": "The product’s own status."
          },
          "stageLabel": {
            "type": "string",
            "example": "In review"
          },
          "dueDate": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          }
        },
        "description": "A self assessment return, Company Tax Return or set of accounts.",
        "required": [
          "id",
          "clientId",
          "clientName",
          "periodLabel",
          "status",
          "stageLabel",
          "dueDate"
        ]
      },
      "SearchResults": {
        "type": "object",
        "properties": {
          "query": {
            "type": "string"
          },
          "searched": {
            "type": "array",
            "description": "The groups searched for this caller.",
            "items": {
              "$ref": "#/components/schemas/SearchGroup"
            }
          },
          "clients": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SearchClient"
            }
          },
          "engagements": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SearchEngagement"
            }
          },
          "sections": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SearchSection"
            }
          },
          "meetings": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SearchMeeting"
            }
          },
          "people": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SearchPerson"
            }
          },
          "taxReturns": {
            "description": "Needs self_assessment:read and Self Assessment.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SearchWorkItem"
            }
          },
          "companyTaxReturns": {
            "description": "Needs corporation_tax:read and Corporation Tax.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SearchWorkItem"
            }
          },
          "accountsSets": {
            "description": "Needs accounts:read and Accounts.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SearchWorkItem"
            }
          }
        },
        "description": "Matches grouped by kind. Each group is searched only when you may read it: engagements and sections need engagements:read and Working Papers, meetings need meetings:read and Meetings, people need settings:read. `searched` lists the groups that were.",
        "required": [
          "query",
          "searched",
          "clients",
          "engagements",
          "sections",
          "meetings",
          "people"
        ]
      },
      "ProductStatus": {
        "type": "string",
        "enum": [
          "available",
          "beta",
          "retired"
        ],
        "description": "beta: available, still changing. retired: no longer offered."
      },
      "Product": {
        "type": "object",
        "properties": {
          "key": {
            "type": "string",
            "example": "meetings",
            "pattern": "^[a-z][a-z0-9_]{1,39}$",
            "description": "Stable id, e.g. working_papers or meetings."
          },
          "name": {
            "type": "string",
            "example": "Meetings"
          },
          "description": {
            "type": "string"
          },
          "path": {
            "type": "string",
            "example": "/meetings",
            "description": "Where the product opens in the web app."
          },
          "icon": {
            "type": "string",
            "example": "lucideVideo",
            "description": "A lucide icon name."
          },
          "status": {
            "description": "beta: available, still changing. retired: no longer offered.",
            "allOf": [
              {
                "$ref": "#/components/schemas/ProductStatus"
              }
            ]
          },
          "selfServeTrial": {
            "type": "boolean",
            "description": "A firm admin can start a trial without asking Tolvi."
          },
          "trialDays": {
            "type": "integer",
            "minimum": 0,
            "description": "Length of a self-serve trial."
          }
        },
        "description": "A product in the Tolvi suite.",
        "required": [
          "key",
          "name",
          "description",
          "path",
          "icon",
          "status",
          "selfServeTrial",
          "trialDays"
        ]
      },
      "ProductUse": {
        "type": "string",
        "enum": [
          "full",
          "read_only"
        ],
        "description": "read_only while the product is suspended."
      },
      "MyProduct": {
        "type": "object",
        "properties": {
          "key": {
            "type": "string",
            "example": "meetings",
            "pattern": "^[a-z][a-z0-9_]{1,39}$",
            "description": "Stable id, e.g. working_papers or meetings."
          },
          "name": {
            "type": "string",
            "example": "Meetings"
          },
          "description": {
            "type": "string"
          },
          "path": {
            "type": "string",
            "example": "/meetings",
            "description": "Where the product opens in the web app."
          },
          "icon": {
            "type": "string",
            "example": "lucideVideo",
            "description": "A lucide icon name."
          },
          "status": {
            "description": "beta: available, still changing. retired: no longer offered.",
            "allOf": [
              {
                "$ref": "#/components/schemas/ProductStatus"
              }
            ]
          },
          "selfServeTrial": {
            "type": "boolean",
            "description": "A firm admin can start a trial without asking Tolvi."
          },
          "trialDays": {
            "type": "integer",
            "minimum": 0,
            "description": "Length of a self-serve trial."
          },
          "firmStatus": {
            "description": "The firm’s hold on it. suspended: read-only until billing is sorted out.",
            "allOf": [
              {
                "$ref": "#/components/schemas/FirmProductStatus"
              }
            ]
          },
          "use": {
            "description": "read_only while the product is suspended.",
            "allOf": [
              {
                "$ref": "#/components/schemas/ProductUse"
              }
            ]
          },
          "trialEndsAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          }
        },
        "description": "A product you can open in this firm.",
        "required": [
          "key",
          "name",
          "description",
          "path",
          "icon",
          "status",
          "selfServeTrial",
          "trialDays",
          "firmStatus",
          "use",
          "trialEndsAt"
        ]
      },
      "ProductAccessMode": {
        "type": "string",
        "enum": [
          "everyone",
          "assigned"
        ],
        "description": "everyone: every member of the firm. assigned: only people given access."
      },
      "FirmProductSource": {
        "type": "string",
        "enum": [
          "included",
          "trial",
          "subscription",
          "manual"
        ],
        "description": "included: part of every firm. trial, subscription, or manual (set by Tolvi)."
      },
      "FirmProduct": {
        "type": "object",
        "properties": {
          "key": {
            "type": "string",
            "example": "meetings",
            "pattern": "^[a-z][a-z0-9_]{1,39}$"
          },
          "name": {
            "type": "string"
          },
          "path": {
            "type": "string"
          },
          "icon": {
            "type": "string"
          },
          "productStatus": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ProductStatus"
              }
            ]
          },
          "status": {
            "allOf": [
              {
                "$ref": "#/components/schemas/FirmProductStatus"
              }
            ]
          },
          "accessMode": {
            "description": "everyone: every member of the firm. assigned: only people given access.",
            "allOf": [
              {
                "$ref": "#/components/schemas/ProductAccessMode"
              }
            ]
          },
          "source": {
            "description": "included: part of every firm. trial, subscription, or manual (set by Tolvi).",
            "allOf": [
              {
                "$ref": "#/components/schemas/FirmProductSource"
              }
            ]
          },
          "startedAt": {
            "type": "string",
            "format": "date-time"
          },
          "trialEndsAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "peopleWithAccess": {
            "type": "integer",
            "minimum": 0
          }
        },
        "description": "A product the firm has, and who can use it.",
        "required": [
          "key",
          "name",
          "path",
          "icon",
          "productStatus",
          "status",
          "accessMode",
          "source",
          "startedAt",
          "trialEndsAt",
          "peopleWithAccess"
        ]
      },
      "FirmProductPatch": {
        "type": "object",
        "properties": {
          "accessMode": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ProductAccessMode"
              }
            ]
          }
        },
        "required": [
          "accessMode"
        ]
      },
      "ProductAccessMember": {
        "type": "object",
        "properties": {
          "userId": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "email": {
            "type": "string",
            "format": "email"
          },
          "initials": {
            "type": "string",
            "example": "GL"
          },
          "role": {
            "allOf": [
              {
                "$ref": "#/components/schemas/MembershipRole"
              }
            ]
          },
          "staffRole": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/StaffRole"
              },
              {
                "type": "null"
              }
            ]
          },
          "isAdmin": {
            "type": "boolean"
          },
          "products": {
            "description": "Product keys they can open now.",
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "assigned": {
            "description": "Product keys they have been given, whatever the access mode.",
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        },
        "description": "One person’s row in the people × products view.",
        "required": [
          "userId",
          "name",
          "email",
          "initials",
          "role",
          "staffRole",
          "isAdmin",
          "products",
          "assigned"
        ]
      },
      "ProductAccessMatrix": {
        "type": "object",
        "properties": {
          "products": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/FirmProduct"
            }
          },
          "members": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ProductAccessMember"
            }
          }
        },
        "description": "The firm’s products and, for each person, which they can use.",
        "required": [
          "products",
          "members"
        ]
      },
      "MeetingStatusGroup": {
        "type": "string",
        "enum": [
          "upcoming",
          "in_progress",
          "ready",
          "not_recorded"
        ]
      },
      "MeetingPlatform": {
        "type": "string",
        "enum": [
          "zoom",
          "google_meet",
          "microsoft_teams",
          "webex",
          "goto_meeting"
        ]
      },
      "MeetingSource": {
        "type": "string",
        "enum": [
          "link",
          "calendar"
        ],
        "description": "link: pasted on the Meetings page. calendar: ticked on the Calendar page."
      },
      "MeetingOutputStatus": {
        "type": "string",
        "enum": [
          "pending",
          "transcribing",
          "summarising",
          "ready",
          "failed"
        ]
      },
      "MeetingSummary": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "title": {
            "type": "string"
          },
          "clientId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "clientName": {
            "type": [
              "string",
              "null"
            ]
          },
          "platform": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/MeetingPlatform"
              },
              {
                "type": "null"
              }
            ]
          },
          "meetingUrl": {
            "type": "string",
            "format": "uri"
          },
          "joinAt": {
            "type": "string",
            "format": "date-time"
          },
          "source": {
            "description": "link: pasted on the Meetings page. calendar: ticked on the Calendar page.",
            "allOf": [
              {
                "$ref": "#/components/schemas/MeetingSource"
              }
            ]
          },
          "status": {
            "description": "scheduling: being sent to Recall. scheduled: will join at joinAt. joining, waiting_room (someone must admit it), in_call, recording. processing: the call ended; the transcript and summary are on their way. ready: transcript and summary filed. failed: see statusDetail. cancelled.",
            "allOf": [
              {
                "$ref": "#/components/schemas/MeetingStatus"
              }
            ]
          },
          "statusDetail": {
            "type": [
              "string",
              "null"
            ],
            "description": "Why it failed or is held up, in words."
          },
          "startedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "endedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "createdById": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "createdByName": {
            "type": [
              "string",
              "null"
            ]
          },
          "outputStatus": {
            "allOf": [
              {
                "$ref": "#/components/schemas/MeetingOutputStatus"
              }
            ]
          },
          "actionCount": {
            "type": "integer",
            "minimum": 0
          },
          "openActionCount": {
            "type": "integer",
            "minimum": 0,
            "description": "Next steps not yet sorted with Create follow-ups (made into a review point or a client request, or skipped)."
          },
          "recordingDeletedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "When the recording (audio and video) was deleted at Recall. Tolvi keeps only the transcript and summary."
          },
          "billableMinutes": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 0,
            "description": "Minutes this meeting counts against the firm’s monthly allowance: the recording’s length, rounded up. Null until it ends."
          }
        },
        "description": "A meeting a note-taker was sent to.",
        "required": [
          "id",
          "title",
          "clientId",
          "clientName",
          "platform",
          "meetingUrl",
          "joinAt",
          "source",
          "status",
          "statusDetail",
          "startedAt",
          "endedAt",
          "createdById",
          "createdByName",
          "outputStatus",
          "actionCount",
          "openActionCount",
          "recordingDeletedAt",
          "billableMinutes"
        ]
      },
      "LaunchMeetingRequest": {
        "type": "object",
        "properties": {
          "meetingUrl": {
            "type": "string",
            "format": "uri",
            "example": "https://teams.microsoft.com/l/meetup-join/…",
            "description": "A Zoom, Google Meet, Microsoft Teams, Webex or GoTo Meeting link."
          },
          "title": {
            "type": "string",
            "maxLength": 200
          },
          "clientId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid",
            "description": "The client to file it against."
          },
          "joinAt": {
            "type": "string",
            "format": "date-time",
            "description": "When to join. Now if left out."
          }
        },
        "required": [
          "meetingUrl"
        ]
      },
      "MeetingActionSide": {
        "type": "string",
        "enum": [
          "firm",
          "client",
          "unclear"
        ]
      },
      "MeetingAction": {
        "type": "object",
        "properties": {
          "text": {
            "type": "string"
          },
          "owner": {
            "type": [
              "string",
              "null"
            ],
            "description": "As named in the meeting."
          },
          "side": {
            "allOf": [
              {
                "$ref": "#/components/schemas/MeetingActionSide"
              }
            ]
          },
          "due": {
            "type": [
              "string",
              "null"
            ],
            "description": "As said in the meeting, e.g. \"by Friday\"."
          }
        },
        "description": "An action agreed in the meeting (drafted by Tolvi AI).",
        "required": [
          "text",
          "owner",
          "side",
          "due"
        ]
      },
      "MeetingFollowUpEmail": {
        "type": "object",
        "properties": {
          "subject": {
            "type": "string"
          },
          "body": {
            "type": "string",
            "description": "Plain text."
          }
        },
        "description": "A draft email to the client recapping the meeting (drafted by Tolvi AI). Tolvi never sends it.",
        "required": [
          "subject",
          "body"
        ]
      },
      "MeetingTurn": {
        "type": "object",
        "properties": {
          "speaker": {
            "type": "string"
          },
          "startSeconds": {
            "type": "integer",
            "minimum": 0,
            "description": "Seconds from the start of the recording."
          },
          "text": {
            "type": "string"
          }
        },
        "description": "One speaker turn of the transcript.",
        "required": [
          "speaker",
          "startSeconds",
          "text"
        ]
      },
      "MeetingFollowUpKind": {
        "type": "string",
        "enum": [
          "review_point",
          "client_request",
          "skip"
        ]
      },
      "MeetingFollowUp": {
        "type": "object",
        "properties": {
          "actionIndex": {
            "type": "integer",
            "minimum": 0,
            "description": "The next step’s position in actions (from 0)."
          },
          "kind": {
            "allOf": [
              {
                "$ref": "#/components/schemas/MeetingFollowUpKind"
              }
            ]
          },
          "engagementId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "reviewPointId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "sectionCode": {
            "type": [
              "string",
              "null"
            ],
            "description": "The W/P section the review point is on (null: the engagement as a whole)."
          },
          "text": {
            "type": [
              "string",
              "null"
            ],
            "description": "Client requests: the line added to the follow-up email."
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "createdById": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          }
        },
        "description": "What a next step became: a review point on the engagement, a request in the follow-up email, or skipped.",
        "required": [
          "actionIndex",
          "kind",
          "engagementId",
          "reviewPointId",
          "sectionCode",
          "text",
          "createdAt",
          "createdById"
        ]
      },
      "MeetingDetail": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "title": {
            "type": "string"
          },
          "clientId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "clientName": {
            "type": [
              "string",
              "null"
            ]
          },
          "platform": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/MeetingPlatform"
              },
              {
                "type": "null"
              }
            ]
          },
          "meetingUrl": {
            "type": "string",
            "format": "uri"
          },
          "joinAt": {
            "type": "string",
            "format": "date-time"
          },
          "source": {
            "description": "link: pasted on the Meetings page. calendar: ticked on the Calendar page.",
            "allOf": [
              {
                "$ref": "#/components/schemas/MeetingSource"
              }
            ]
          },
          "status": {
            "description": "scheduling: being sent to Recall. scheduled: will join at joinAt. joining, waiting_room (someone must admit it), in_call, recording. processing: the call ended; the transcript and summary are on their way. ready: transcript and summary filed. failed: see statusDetail. cancelled.",
            "allOf": [
              {
                "$ref": "#/components/schemas/MeetingStatus"
              }
            ]
          },
          "statusDetail": {
            "type": [
              "string",
              "null"
            ],
            "description": "Why it failed or is held up, in words."
          },
          "startedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "endedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "createdById": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "createdByName": {
            "type": [
              "string",
              "null"
            ]
          },
          "outputStatus": {
            "allOf": [
              {
                "$ref": "#/components/schemas/MeetingOutputStatus"
              }
            ]
          },
          "actionCount": {
            "type": "integer",
            "minimum": 0
          },
          "openActionCount": {
            "type": "integer",
            "minimum": 0,
            "description": "Next steps not yet sorted with Create follow-ups (made into a review point or a client request, or skipped)."
          },
          "recordingDeletedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "When the recording (audio and video) was deleted at Recall. Tolvi keeps only the transcript and summary."
          },
          "billableMinutes": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 0,
            "description": "Minutes this meeting counts against the firm’s monthly allowance: the recording’s length, rounded up. Null until it ends."
          },
          "summary": {
            "type": [
              "string",
              "null"
            ]
          },
          "keyPoints": {
            "description": "Takeaways: facts, figures and decisions worth keeping on the client file.",
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "actions": {
            "description": "Next steps: what each side agreed to do.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/MeetingAction"
            }
          },
          "openQuestions": {
            "description": "Questions raised in the meeting that were not settled. Empty for meetings summarised before 25 Oct 2026.",
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "followUpEmail": {
            "description": "A draft email to the client recapping the meeting, with any client requests from Create follow-ups listed before the sign-off; null if nothing was agreed. Tolvi never sends it.",
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/MeetingFollowUpEmail"
              }
            ]
          },
          "transcript": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/MeetingTurn"
            }
          },
          "aiTokens": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 0,
            "description": "Tolvi AI tokens the summary used."
          },
          "outputFailure": {
            "type": [
              "string",
              "null"
            ]
          },
          "followUps": {
            "description": "What each next step became (Create follow-ups), by its position in actions.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/MeetingFollowUp"
            }
          }
        },
        "description": "A meeting with its transcript and the Tolvi AI write-up: summary, takeaways, next steps, open questions and a draft follow-up email.",
        "required": [
          "id",
          "title",
          "clientId",
          "clientName",
          "platform",
          "meetingUrl",
          "joinAt",
          "source",
          "status",
          "statusDetail",
          "startedAt",
          "endedAt",
          "createdById",
          "createdByName",
          "outputStatus",
          "actionCount",
          "openActionCount",
          "recordingDeletedAt",
          "billableMinutes",
          "summary",
          "keyPoints",
          "actions",
          "openQuestions",
          "followUpEmail",
          "transcript",
          "aiTokens",
          "outputFailure",
          "followUps"
        ]
      },
      "MeetingsUsage": {
        "type": "object",
        "properties": {
          "month": {
            "type": "string",
            "example": "2026-10",
            "description": "The calendar month (UTC)."
          },
          "minutesUsed": {
            "type": "integer",
            "minimum": 0
          },
          "planId": {
            "type": [
              "string",
              "null"
            ],
            "example": "meetings_team",
            "description": "Null on a trial (300 minutes)."
          },
          "allowance": {
            "type": "integer",
            "minimum": 0
          },
          "remaining": {
            "type": "integer",
            "minimum": 0
          },
          "overageMinutes": {
            "type": "integer",
            "minimum": 0,
            "description": "Minutes beyond the allowance; billed at 3p each on a paid plan. Recording never stops."
          },
          "thresholdsReached": {
            "description": "80 and 100 once reached.",
            "type": "array",
            "items": {
              "type": "number"
            }
          }
        },
        "description": "Recorded minutes this month against the firm’s Meetings allowance.",
        "required": [
          "month",
          "minutesUsed",
          "planId",
          "allowance",
          "remaining",
          "overageMinutes",
          "thresholdsReached"
        ]
      },
      "UpdateMeetingRequest": {
        "type": "object",
        "properties": {
          "title": {
            "type": "string",
            "maxLength": 200
          },
          "clientId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          }
        }
      },
      "MeetingFollowUpItem": {
        "type": "object",
        "properties": {
          "actionIndex": {
            "type": "integer",
            "minimum": 0,
            "description": "The next step’s position in the meeting’s actions (from 0)."
          },
          "kind": {
            "description": "review_point: raised on the engagement (reviewers, managers and partners). client_request: listed in the follow-up email. skip: nothing, but the step counts as sorted.",
            "allOf": [
              {
                "$ref": "#/components/schemas/MeetingFollowUpKind"
              }
            ]
          },
          "sectionCode": {
            "type": [
              "string",
              "null"
            ],
            "example": "J",
            "description": "review_point: the W/P section; null or left out for the engagement as a whole."
          },
          "text": {
            "type": "string",
            "maxLength": 2000,
            "description": "The wording to use instead of the next step’s own."
          },
          "due": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 100,
            "example": "by Friday",
            "description": "When it is due, in words; added to the point or request."
          },
          "mentionUserId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid",
            "description": "review_point: a person to @mention on it."
          }
        },
        "required": [
          "actionIndex",
          "kind"
        ]
      },
      "CreateMeetingFollowUpsRequest": {
        "type": "object",
        "properties": {
          "engagementId": {
            "type": "string",
            "format": "uuid",
            "description": "The engagement the review points go on: one of the filed client’s. Required when any item is a review_point."
          },
          "items": {
            "minItems": 1,
            "maxItems": 50,
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/MeetingFollowUpItem"
            }
          }
        },
        "required": [
          "items"
        ]
      },
      "CalendarPlatform": {
        "type": "string",
        "enum": [
          "microsoft_outlook"
        ]
      },
      "CalendarEvent": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "startTime": {
            "type": "string",
            "format": "date-time"
          },
          "endTime": {
            "type": "string",
            "format": "date-time"
          },
          "meetingUrl": {
            "type": [
              "string",
              "null"
            ]
          },
          "platform": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/MeetingPlatform"
              },
              {
                "type": "null"
              }
            ]
          },
          "notetaker": {
            "type": "boolean",
            "description": "A note-taker will join: you ticked it."
          },
          "meetingId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "clientId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "clientName": {
            "type": [
              "string",
              "null"
            ],
            "description": "The name of the client the meeting is filed against."
          },
          "takenBy": {
            "type": [
              "string",
              "null"
            ],
            "description": "A colleague already sent a note-taker to this meeting: their name."
          },
          "suggestedClientId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid",
            "description": "A client whose name is in the meeting’s title: a suggestion for filing it."
          },
          "suggestedClientName": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "description": "An upcoming meeting in your connected calendar (the next 28 days).",
        "required": [
          "id",
          "title",
          "startTime",
          "endTime",
          "meetingUrl",
          "platform",
          "notetaker",
          "meetingId",
          "clientId",
          "takenBy"
        ]
      },
      "MyCalendar": {
        "type": "object",
        "properties": {
          "available": {
            "type": "boolean"
          },
          "connected": {
            "type": "boolean"
          },
          "status": {
            "type": [
              "string",
              "null"
            ],
            "description": "connecting, connected or disconnected."
          },
          "platform": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/CalendarPlatform"
              },
              {
                "type": "null"
              }
            ]
          },
          "email": {
            "type": [
              "string",
              "null"
            ]
          },
          "events": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CalendarEvent"
            }
          }
        },
        "description": "Your connected calendar and its upcoming meetings.",
        "required": [
          "available",
          "connected",
          "status",
          "platform",
          "email",
          "events"
        ]
      },
      "CalendarConnectStart": {
        "type": "object",
        "properties": {
          "authorizeUrl": {
            "type": "string",
            "format": "uri",
            "description": "Send the browser here to sign in to Microsoft."
          }
        },
        "required": [
          "authorizeUrl"
        ]
      },
      "CalendarNotetakerRequest": {
        "type": "object",
        "properties": {
          "clientId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid",
            "description": "The client to file it against."
          }
        }
      },
      "BooksSignUp": {
        "type": "object",
        "properties": {
          "businessName": {
            "type": "string",
            "maxLength": 200,
            "example": "Abbey Bakery Ltd"
          },
          "entityType": {
            "allOf": [
              {
                "$ref": "#/components/schemas/EntityType"
              }
            ]
          },
          "email": {
            "type": "string",
            "format": "email",
            "maxLength": 254
          }
        },
        "description": "A business signing up to Tolvi Books on its own.",
        "required": [
          "businessName",
          "entityType",
          "email"
        ]
      },
      "VatScheme": {
        "type": "string",
        "enum": [
          "standard",
          "cash_accounting",
          "flat_rate",
          "annual_accounting"
        ]
      },
      "BooksCurrency": {
        "type": "string",
        "enum": [
          "GBP"
        ]
      },
      "Business": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "The business’s tenant id (send it as x-business-id to work in its books as its accountant)."
          },
          "legalName": {
            "type": "string",
            "example": "Abbey Bakery Ltd"
          },
          "tradingName": {
            "type": [
              "string",
              "null"
            ]
          },
          "entityType": {
            "allOf": [
              {
                "$ref": "#/components/schemas/EntityType"
              }
            ]
          },
          "companyNumber": {
            "type": [
              "string",
              "null"
            ],
            "example": "01234567"
          },
          "vatRegistered": {
            "type": "boolean"
          },
          "vatNumber": {
            "type": [
              "string",
              "null"
            ],
            "example": "123456789",
            "description": "9 digits (12 for a group branch), without GB."
          },
          "vatScheme": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/VatScheme"
              },
              {
                "type": "null"
              }
            ]
          },
          "vatRegisteredFrom": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31"
          },
          "yearEndDay": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 1,
            "maximum": 31
          },
          "yearEndMonth": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 1,
            "maximum": 12
          },
          "booksStartDate": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31",
            "description": "The first day the books cover."
          },
          "baseCurrency": {
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksCurrency"
              }
            ]
          },
          "custodianFirmId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid",
            "description": "The accountancy practice that set the business up, until an owner claims it."
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "description": "A business’s profile in Tolvi Books: who it is, its VAT registration and its year end.",
        "required": [
          "id",
          "legalName",
          "tradingName",
          "entityType",
          "companyNumber",
          "vatRegistered",
          "vatNumber",
          "vatScheme",
          "vatRegisteredFrom",
          "yearEndDay",
          "yearEndMonth",
          "booksStartDate",
          "baseCurrency",
          "custodianFirmId",
          "createdAt",
          "updatedAt"
        ]
      },
      "UpdateBusiness": {
        "type": "object",
        "properties": {
          "legalName": {
            "type": "string",
            "maxLength": 200
          },
          "tradingName": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 200
          },
          "entityType": {
            "allOf": [
              {
                "$ref": "#/components/schemas/EntityType"
              }
            ]
          },
          "companyNumber": {
            "type": [
              "string",
              "null"
            ],
            "pattern": "^[A-Za-z0-9 ]{8,10}$"
          },
          "vatRegistered": {
            "type": "boolean"
          },
          "vatNumber": {
            "type": [
              "string",
              "null"
            ]
          },
          "vatScheme": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/VatScheme"
              },
              {
                "type": "null"
              }
            ]
          },
          "vatRegisteredFrom": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31"
          },
          "yearEndDay": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 1,
            "maximum": 31
          },
          "yearEndMonth": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 1,
            "maximum": 12
          },
          "booksStartDate": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31"
          }
        },
        "description": "Only the fields sent change. VAT details need a signed-in person."
      },
      "PracticeLinkStatus": {
        "type": "string",
        "enum": [
          "invited_by_business",
          "requested_by_firm",
          "active",
          "ended"
        ],
        "description": "invited_by_business: waiting for the practice to accept. requested_by_firm: waiting for the business to approve. active: the practice can work in the books. ended: never active again."
      },
      "PracticeAccess": {
        "type": "string",
        "enum": [
          "read_only",
          "year_end",
          "full_bookkeeping"
        ],
        "description": "read_only: see the books, export, pull the TB. year_end: also post year-end adjustments. full_bookkeeping: also keep the books."
      },
      "LinkConsentBasis": {
        "type": "string",
        "enum": [
          "owner_consent",
          "practice_provisioned"
        ]
      },
      "LinkSide": {
        "type": "string",
        "enum": [
          "business",
          "firm"
        ]
      },
      "PracticeLink": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "status": {
            "description": "invited_by_business: waiting for the practice to accept. requested_by_firm: waiting for the business to approve. active: the practice can work in the books. ended: never active again.",
            "allOf": [
              {
                "$ref": "#/components/schemas/PracticeLinkStatus"
              }
            ]
          },
          "access": {
            "description": "read_only: see the books, export, pull the TB. year_end: also post year-end adjustments. full_bookkeeping: also keep the books.",
            "allOf": [
              {
                "$ref": "#/components/schemas/PracticeAccess"
              }
            ]
          },
          "vatAgent": {
            "type": "boolean",
            "description": "The practice may prepare (and, once built, submit) VAT returns. At most one practice at a time."
          },
          "billedBy": {
            "allOf": [
              {
                "$ref": "#/components/schemas/LinkBilledBy"
              }
            ]
          },
          "consentBasis": {
            "allOf": [
              {
                "$ref": "#/components/schemas/LinkConsentBasis"
              }
            ]
          },
          "businessId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "businessName": {
            "type": [
              "string",
              "null"
            ]
          },
          "firmId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "firmName": {
            "type": [
              "string",
              "null"
            ]
          },
          "invitedEmail": {
            "type": [
              "string",
              "null"
            ]
          },
          "requestedEmail": {
            "type": [
              "string",
              "null"
            ]
          },
          "expiresAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "activatedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "endedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "endedBySide": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/LinkSide"
              },
              {
                "type": "null"
              }
            ]
          }
        },
        "description": "An accountancy practice’s access to a business’s books, as either side sees it.",
        "required": [
          "id",
          "status",
          "access",
          "vatAgent",
          "billedBy",
          "consentBasis",
          "businessId",
          "businessName",
          "firmId",
          "firmName",
          "invitedEmail",
          "requestedEmail",
          "expiresAt",
          "createdAt",
          "activatedAt",
          "endedAt",
          "endedBySide"
        ]
      },
      "InviteAccountant": {
        "type": "object",
        "properties": {
          "email": {
            "type": "string",
            "format": "email",
            "maxLength": 254,
            "description": "The accountant who will accept, signed in to their practice in Tolvi."
          },
          "access": {
            "description": "read_only: see the books, export, pull the TB. year_end: also post year-end adjustments. full_bookkeeping: also keep the books.",
            "allOf": [
              {
                "$ref": "#/components/schemas/PracticeAccess"
              }
            ]
          },
          "vatAgent": {
            "type": "boolean"
          }
        },
        "required": [
          "email",
          "access"
        ]
      },
      "ChangePracticeLink": {
        "type": "object",
        "properties": {
          "access": {
            "description": "read_only: see the books, export, pull the TB. year_end: also post year-end adjustments. full_bookkeeping: also keep the books.",
            "allOf": [
              {
                "$ref": "#/components/schemas/PracticeAccess"
              }
            ]
          },
          "vatAgent": {
            "type": "boolean"
          },
          "billedBy": {
            "allOf": [
              {
                "$ref": "#/components/schemas/LinkBilledBy"
              }
            ]
          }
        },
        "description": "Only the fields sent change."
      },
      "EndPracticeLink": {
        "type": "object",
        "properties": {
          "reason": {
            "type": "string",
            "maxLength": 500
          }
        }
      },
      "ApprovePracticeLinkRequest": {
        "type": "object",
        "properties": {
          "access": {
            "description": "Defaults to what the practice asked for.",
            "allOf": [
              {
                "$ref": "#/components/schemas/PracticeAccess"
              }
            ]
          },
          "vatAgent": {
            "type": "boolean"
          }
        }
      },
      "RequestBooksAccess": {
        "type": "object",
        "properties": {
          "email": {
            "type": "string",
            "format": "email",
            "maxLength": 254,
            "description": "The business owner’s email: they approve in Tolvi Books."
          },
          "access": {
            "description": "read_only: see the books, export, pull the TB. year_end: also post year-end adjustments. full_bookkeeping: also keep the books.",
            "allOf": [
              {
                "$ref": "#/components/schemas/PracticeAccess"
              }
            ]
          }
        },
        "required": [
          "email",
          "access"
        ]
      },
      "PracticeLinkToken": {
        "type": "object",
        "properties": {
          "token": {
            "type": "string",
            "minLength": 20,
            "maxLength": 200
          }
        },
        "description": "The token from the invitation email.",
        "required": [
          "token"
        ]
      },
      "PracticeLinkInvitationPreview": {
        "type": "object",
        "properties": {
          "businessName": {
            "type": [
              "string",
              "null"
            ]
          },
          "access": {
            "description": "read_only: see the books, export, pull the TB. year_end: also post year-end adjustments. full_bookkeeping: also keep the books.",
            "allOf": [
              {
                "$ref": "#/components/schemas/PracticeAccess"
              }
            ]
          },
          "vatAgent": {
            "type": "boolean"
          },
          "expiresAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "expired": {
            "type": "boolean"
          }
        },
        "required": [
          "businessName",
          "access",
          "vatAgent",
          "expiresAt",
          "expired"
        ]
      },
      "ProvisionBusiness": {
        "type": "object",
        "properties": {
          "legalName": {
            "type": "string",
            "maxLength": 200
          },
          "tradingName": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 200
          },
          "entityType": {
            "allOf": [
              {
                "$ref": "#/components/schemas/EntityType"
              }
            ]
          },
          "companyNumber": {
            "type": [
              "string",
              "null"
            ]
          },
          "yearEndDay": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 1,
            "maximum": 31
          },
          "yearEndMonth": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 1,
            "maximum": 12
          },
          "booksStartDate": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31"
          },
          "billedBy": {
            "description": "Who pays for Tolvi Books. Defaults to the practice.",
            "allOf": [
              {
                "$ref": "#/components/schemas/LinkBilledBy"
              }
            ]
          },
          "ownerEmail": {
            "type": "string",
            "format": "email",
            "description": "Invite the owner now (they can also be invited later)."
          }
        },
        "description": "A practice setting Tolvi Books up for a client. The practice looks after it until the owner joins.",
        "required": [
          "legalName",
          "entityType"
        ]
      },
      "ProvisionedBusiness": {
        "type": "object",
        "properties": {
          "business": {
            "$ref": "#/components/schemas/Business"
          },
          "link": {
            "$ref": "#/components/schemas/PracticeLink"
          }
        },
        "description": "The business a practice set up, and the practice’s link to it.",
        "required": [
          "business",
          "link"
        ]
      },
      "OwnerInvitation": {
        "type": "object",
        "properties": {
          "email": {
            "type": "string",
            "format": "email",
            "maxLength": 254
          }
        },
        "required": [
          "email"
        ]
      },
      "BooksLinkSource": {
        "type": "string",
        "enum": [
          "tolvi_books"
        ],
        "description": "Always tolvi_books: reached through a practice link, not OAuth."
      },
      "BooksHealth": {
        "type": "object",
        "properties": {
          "entries": {
            "type": "integer",
            "minimum": 0,
            "description": "Ledger entries posted."
          },
          "lastPostedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "lastEntryDate": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31",
            "description": "The latest date any entry is dated."
          },
          "receiptsToReview": {
            "type": "integer",
            "minimum": 0,
            "description": "Receipts read and waiting to be confirmed."
          },
          "unexplainedBankLines": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 0,
            "description": "Bank lines not yet explained. Null until bank feeds are available."
          },
          "vatRegistered": {
            "type": "boolean"
          },
          "vatScheme": {
            "type": [
              "string",
              "null"
            ],
            "example": "standard"
          },
          "nextVatDue": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31",
            "description": "The next VAT return due. Null until MTD VAT returns are available."
          }
        },
        "description": "A linked client’s books at a glance, as its accountant sees them.",
        "required": [
          "entries",
          "lastPostedAt",
          "lastEntryDate",
          "receiptsToReview",
          "unexplainedBankLines",
          "vatRegistered",
          "vatScheme",
          "nextVatDue"
        ]
      },
      "ClientBooksLink": {
        "type": "object",
        "properties": {
          "clientId": {
            "type": "string",
            "format": "uuid"
          },
          "linked": {
            "type": "boolean"
          },
          "source": {
            "description": "Always tolvi_books: reached through a practice link, not OAuth.",
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksLinkSource"
              }
            ]
          },
          "sourceLabel": {
            "type": "string",
            "example": "Tolvi Books"
          },
          "businessId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid",
            "description": "The business’s tenant id (send it as x-business-id to work in its books)."
          },
          "businessName": {
            "type": [
              "string",
              "null"
            ]
          },
          "practiceLinkId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "linkStatus": {
            "description": "ended: the business (or the firm) ended the link; relink or unlink.",
            "oneOf": [
              {
                "$ref": "#/components/schemas/PracticeLinkStatus"
              },
              {
                "type": "null"
              }
            ]
          },
          "access": {
            "description": "read_only: see the books, export, pull the TB. year_end: also post year-end adjustments. full_bookkeeping: also keep the books.",
            "oneOf": [
              {
                "$ref": "#/components/schemas/PracticeAccess"
              },
              {
                "type": "null"
              }
            ]
          },
          "consentBasis": {
            "description": "practice_provisioned: the firm set the books up and looks after them until the owner joins.",
            "oneOf": [
              {
                "$ref": "#/components/schemas/LinkConsentBasis"
              },
              {
                "type": "null"
              }
            ]
          },
          "linkedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "linkedBy": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "trialBalanceAvailable": {
            "type": "boolean",
            "description": "The trial balance can be pulled straight from the client’s Tolvi Books now (linked, and the link is live)."
          },
          "connectionProvider": {
            "description": "The client’s OAuth connection, when it also has one.",
            "oneOf": [
              {
                "$ref": "#/components/schemas/IntegrationProvider"
              },
              {
                "type": "null"
              }
            ]
          },
          "connectionLabel": {
            "type": [
              "string",
              "null"
            ],
            "example": "Xero"
          },
          "sourceChoice": {
            "description": "When the client has both an OAuth connection and a Tolvi Books link: the one a person chose for its engagements (PUT …/books-link/source). Null until chosen, and with only one source.",
            "oneOf": [
              {
                "$ref": "#/components/schemas/BooksSourcePick"
              },
              {
                "type": "null"
              }
            ]
          },
          "needsSourceChoice": {
            "type": "boolean",
            "description": "The client has both sources and nobody has chosen: trial balance pulls ask until someone does. Tolvi never picks one itself."
          },
          "sourceInUse": {
            "description": "The source the client’s engagements pull their trial balance from now.",
            "oneOf": [
              {
                "$ref": "#/components/schemas/BooksSource"
              },
              {
                "type": "null"
              }
            ]
          },
          "health": {
            "description": "The books at a glance, read through the link; null when not linked or the link has ended.",
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksHealth"
              }
            ]
          }
        },
        "description": "Which business’s Tolvi Books is this client’s, through which of the firm’s practice links. The link is the business’s to grant and end; unlinking here only forgets which client it is.",
        "required": [
          "clientId",
          "linked",
          "source",
          "sourceLabel",
          "businessId",
          "businessName",
          "practiceLinkId",
          "linkStatus",
          "access",
          "consentBasis",
          "linkedAt",
          "linkedBy",
          "trialBalanceAvailable",
          "connectionProvider",
          "connectionLabel",
          "sourceChoice",
          "needsSourceChoice",
          "sourceInUse",
          "health"
        ]
      },
      "BooksLinkCandidate": {
        "type": "object",
        "properties": {
          "practiceLinkId": {
            "type": "string",
            "format": "uuid"
          },
          "businessId": {
            "type": "string",
            "format": "uuid"
          },
          "businessName": {
            "type": [
              "string",
              "null"
            ]
          },
          "access": {
            "description": "read_only: see the books, export, pull the TB. year_end: also post year-end adjustments. full_bookkeeping: also keep the books.",
            "allOf": [
              {
                "$ref": "#/components/schemas/PracticeAccess"
              }
            ]
          },
          "consentBasis": {
            "allOf": [
              {
                "$ref": "#/components/schemas/LinkConsentBasis"
              }
            ]
          },
          "linkedClientId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid",
            "description": "The client it is already linked to, if any."
          },
          "linkedClientName": {
            "type": [
              "string",
              "null"
            ]
          },
          "suggested": {
            "type": "boolean",
            "description": "Not linked yet and named like this client."
          }
        },
        "required": [
          "practiceLinkId",
          "businessId",
          "businessName",
          "access",
          "consentBasis",
          "linkedClientId",
          "linkedClientName",
          "suggested"
        ]
      },
      "BooksLinkCandidateList": {
        "type": "object",
        "properties": {
          "rows": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BooksLinkCandidate"
            }
          }
        },
        "required": [
          "rows"
        ]
      },
      "LinkClientBooks": {
        "type": "object",
        "properties": {
          "practiceLinkId": {
            "type": "string",
            "format": "uuid",
            "description": "One of the firm’s active practice links (GET /clients/{clientId}/books-link/candidates)."
          }
        },
        "required": [
          "practiceLinkId"
        ]
      },
      "ChooseBooksSource": {
        "type": "object",
        "properties": {
          "use": {
            "description": "tolvi_books: the client’s Tolvi Books. connection: its OAuth connection (Xero, QuickBooks, Sage or FreeAgent).",
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksSourcePick"
              }
            ]
          }
        },
        "description": "Which source a client with both an OAuth connection and a Tolvi Books link uses for its engagements.",
        "required": [
          "use"
        ]
      },
      "InviteClientToBooks": {
        "type": "object",
        "properties": {
          "ownerEmail": {
            "type": "string",
            "format": "email",
            "maxLength": 254,
            "description": "Invite the owner now. Without it the firm looks after the books until it invites someone."
          },
          "billedBy": {
            "description": "Who pays for Tolvi Books. Defaults to the practice.",
            "allOf": [
              {
                "$ref": "#/components/schemas/LinkBilledBy"
              }
            ]
          }
        },
        "description": "Set Tolvi Books up for this client from its record, and link it."
      },
      "ClientsBooksRow": {
        "type": "object",
        "properties": {
          "practiceLinkId": {
            "type": "string",
            "format": "uuid"
          },
          "businessId": {
            "type": "string",
            "format": "uuid"
          },
          "businessName": {
            "type": [
              "string",
              "null"
            ]
          },
          "linkStatus": {
            "allOf": [
              {
                "$ref": "#/components/schemas/PracticeLinkStatus"
              }
            ]
          },
          "access": {
            "description": "read_only: see the books, export, pull the TB. year_end: also post year-end adjustments. full_bookkeeping: also keep the books.",
            "allOf": [
              {
                "$ref": "#/components/schemas/PracticeAccess"
              }
            ]
          },
          "consentBasis": {
            "allOf": [
              {
                "$ref": "#/components/schemas/LinkConsentBasis"
              }
            ]
          },
          "clientId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid",
            "description": "The firm’s client these books are, once linked."
          },
          "clientName": {
            "type": [
              "string",
              "null"
            ]
          },
          "health": {
            "description": "Null when the link has ended.",
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksHealth"
              }
            ]
          }
        },
        "description": "One business’s books the firm reaches through a practice link, with the client it is (if linked) and its health.",
        "required": [
          "practiceLinkId",
          "businessId",
          "businessName",
          "linkStatus",
          "access",
          "consentBasis",
          "clientId",
          "clientName",
          "health"
        ]
      },
      "ClientsBooksList": {
        "type": "object",
        "properties": {
          "rows": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ClientsBooksRow"
            }
          }
        },
        "required": [
          "rows"
        ]
      },
      "PostBackAction": {
        "type": "string",
        "enum": [
          "post",
          "reverse"
        ],
        "description": "reverse: undoes an earlier post-back of a journal that has changed or gone."
      },
      "PostBackLine": {
        "type": "object",
        "properties": {
          "accountCode": {
            "type": "string"
          },
          "accountName": {
            "type": [
              "string",
              "null"
            ]
          },
          "amountPence": {
            "type": "integer",
            "description": "Debit positive, in pence."
          }
        },
        "required": [
          "accountCode",
          "accountName",
          "amountPence"
        ]
      },
      "PostBackEntry": {
        "type": "object",
        "properties": {
          "action": {
            "description": "reverse: undoes an earlier post-back of a journal that has changed or gone.",
            "allOf": [
              {
                "$ref": "#/components/schemas/PostBackAction"
              }
            ]
          },
          "journalRef": {
            "type": [
              "string",
              "null"
            ],
            "example": "J4"
          },
          "date": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "description": {
            "type": "string"
          },
          "dateProblem": {
            "type": [
              "string",
              "null"
            ],
            "description": "Why the books would refuse this date (a lock), or null."
          },
          "lines": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PostBackLine"
            }
          }
        },
        "description": "One ledger entry post-back would make in the client’s books.",
        "required": [
          "action",
          "journalRef",
          "date",
          "description",
          "dateProblem",
          "lines"
        ]
      },
      "PostBackMissingAccount": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string"
          },
          "name": {
            "type": "string"
          }
        },
        "required": [
          "code",
          "name"
        ]
      },
      "PostBackBalance": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "booksBeforePence": {
            "type": "integer",
            "description": "The books at the period end now, debit positive."
          },
          "booksAfterPence": {
            "type": "integer",
            "description": "The books at the period end after post-back."
          },
          "finalPence": {
            "type": "integer",
            "description": "The engagement’s final balance (draft TB plus posted journals)."
          },
          "differencePence": {
            "type": "integer",
            "description": "booksAfterPence less finalPence: nil on every account before post-back can go ahead."
          }
        },
        "required": [
          "code",
          "name",
          "booksBeforePence",
          "booksAfterPence",
          "finalPence",
          "differencePence"
        ]
      },
      "PostBackPreview": {
        "type": "object",
        "properties": {
          "engagementId": {
            "type": "string",
            "format": "uuid"
          },
          "businessId": {
            "type": "string",
            "format": "uuid"
          },
          "businessName": {
            "type": [
              "string",
              "null"
            ]
          },
          "periodEnd": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "ready": {
            "type": "boolean",
            "description": "Nothing stands in the way: post-back can go ahead."
          },
          "problems": {
            "description": "What stands in the way, in words.",
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "entries": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PostBackEntry"
            }
          },
          "unchanged": {
            "type": "integer",
            "minimum": 0,
            "description": "Journals the books already hold exactly, from an earlier post-back."
          },
          "missingAccounts": {
            "description": "Accounts the journals use that the books don’t have (add them in the client’s chart first; nothing is created silently).",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PostBackMissingAccount"
            }
          },
          "balances": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PostBackBalance"
            }
          },
          "agrees": {
            "type": "boolean",
            "description": "After post-back the books agree to the final trial balance on every account."
          },
          "lockedThrough": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31",
            "description": "The year-end (accountant) lock in force now."
          },
          "lockThrough": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31",
            "description": "Post-back locks the books to this date (the period end), unless already locked to it or later."
          }
        },
        "description": "What sending an approved engagement’s posted journals to the client’s Tolvi Books would do: the entries, the books’ trial balance at the period end before and after (which must equal the final trial balance to the penny), and the year-end lock it sets. Nothing is posted.",
        "required": [
          "engagementId",
          "businessId",
          "businessName",
          "periodEnd",
          "ready",
          "problems",
          "entries",
          "unchanged",
          "missingAccounts",
          "balances",
          "agrees",
          "lockedThrough",
          "lockThrough"
        ]
      },
      "PostBackResult": {
        "type": "object",
        "properties": {
          "engagementId": {
            "type": "string",
            "format": "uuid"
          },
          "posted": {
            "type": "integer",
            "minimum": 0
          },
          "reversed": {
            "type": "integer",
            "minimum": 0
          },
          "unchanged": {
            "type": "integer",
            "minimum": 0
          },
          "entrySeqs": {
            "description": "The ledger entries made, in order.",
            "type": "array",
            "items": {
              "type": "number"
            }
          },
          "lockedThrough": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "lockedNow": {
            "type": "boolean",
            "description": "This call set the lock (false when it was already in place)."
          }
        },
        "required": [
          "engagementId",
          "posted",
          "reversed",
          "unchanged",
          "entrySeqs",
          "lockedThrough",
          "lockedNow"
        ]
      },
      "StartBooksFromFinalTbInput": {
        "type": "object",
        "properties": {
          "engagementId": {
            "type": "string",
            "format": "uuid",
            "description": "Defaults to the client’s latest engagement approved at every stage."
          },
          "mapping": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            },
            "description": "Final TB code to an account code in the books."
          }
        }
      },
      "BooksOpeningPlanVia": {
        "type": "string",
        "enum": [
          "mapping",
          "code",
          "lead_line"
        ]
      },
      "BooksOpeningPlanLine": {
        "type": "object",
        "properties": {
          "sourceCode": {
            "type": "string"
          },
          "sourceName": {
            "type": "string"
          },
          "balancePence": {
            "type": "integer"
          },
          "targetCode": {
            "type": "string"
          },
          "targetName": {
            "type": "string"
          },
          "via": {
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksOpeningPlanVia"
              }
            ]
          }
        },
        "required": [
          "sourceCode",
          "sourceName",
          "balancePence",
          "targetCode",
          "targetName",
          "via"
        ]
      },
      "BooksOpeningUnmapped": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "balancePence": {
            "type": "integer"
          },
          "leadLine": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "code",
          "name",
          "balancePence",
          "leadLine"
        ]
      },
      "BooksNormalBalance": {
        "type": "string",
        "enum": [
          "debit",
          "credit"
        ]
      },
      "BooksOpeningEntryLine": {
        "type": "object",
        "properties": {
          "accountId": {
            "type": "string",
            "format": "uuid"
          },
          "accountCode": {
            "type": "string"
          },
          "accountName": {
            "type": "string"
          },
          "ownerName": {
            "type": "string"
          },
          "normalBalance": {
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksNormalBalance"
              }
            ]
          },
          "amountPence": {
            "type": "integer",
            "description": "Debit positive, credit negative."
          },
          "contactName": {
            "type": [
              "string",
              "null"
            ],
            "description": "The customer or supplier, on a control account line split by unpaid invoice or bill."
          }
        },
        "required": [
          "accountId",
          "accountCode",
          "accountName",
          "ownerName",
          "normalBalance",
          "amountPence",
          "contactName"
        ]
      },
      "BooksOpeningAccountRef": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "ownerName": {
            "type": "string"
          }
        },
        "required": [
          "code",
          "name",
          "ownerName"
        ]
      },
      "StartBooksFromFinalTbPreview": {
        "type": "object",
        "properties": {
          "ready": {
            "type": "boolean"
          },
          "problems": {
            "description": "What stands in the way, in words.",
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "warnings": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "engagementId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "periodEnd": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31"
          },
          "startDate": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31",
            "description": "The day after the period end."
          },
          "businessId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "businessName": {
            "type": [
              "string",
              "null"
            ]
          },
          "alreadyPosted": {
            "type": "boolean"
          },
          "plan": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BooksOpeningPlanLine"
            }
          },
          "unmapped": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BooksOpeningUnmapped"
            }
          },
          "lines": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BooksOpeningEntryLine"
            }
          },
          "suspensePence": {
            "type": "integer"
          },
          "accounts": {
            "description": "The books’ accounts, to map an unplaced balance to.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BooksOpeningAccountRef"
            }
          }
        },
        "description": "The opening entry the client’s books would get from a final trial balance, mapped through the lead lines. Nothing is posted.",
        "required": [
          "ready",
          "problems",
          "warnings",
          "engagementId",
          "periodEnd",
          "startDate",
          "businessId",
          "businessName",
          "alreadyPosted",
          "plan",
          "unmapped",
          "lines",
          "suspensePence",
          "accounts"
        ]
      },
      "StartBooksFromFinalTbStatus": {
        "type": "string",
        "enum": [
          "posted"
        ]
      },
      "StartBooksFromFinalTbResult": {
        "type": "object",
        "properties": {
          "entryId": {
            "type": "string",
            "format": "uuid"
          },
          "seq": {
            "type": "integer"
          },
          "startDate": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "suspensePence": {
            "type": "integer"
          },
          "status": {
            "allOf": [
              {
                "$ref": "#/components/schemas/StartBooksFromFinalTbStatus"
              }
            ]
          }
        },
        "required": [
          "entryId",
          "seq",
          "startDate",
          "suspensePence",
          "status"
        ]
      },
      "BooksOwnerCategory": {
        "type": "string",
        "enum": [
          "sales",
          "other_income",
          "direct_costs",
          "staff",
          "premises",
          "travel",
          "office",
          "marketing",
          "professional",
          "finance_costs",
          "other_costs",
          "write_offs",
          "tax",
          "bank_and_cash",
          "owed_to_you",
          "you_owe",
          "equipment",
          "stock",
          "owner",
          "behind_the_scenes"
        ]
      },
      "BooksAccountClass": {
        "type": "string",
        "enum": [
          "asset",
          "liability",
          "equity",
          "income",
          "expense"
        ]
      },
      "BooksAccount": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "code": {
            "type": "string",
            "example": "6110",
            "description": "Unique in the business; never changes."
          },
          "name": {
            "type": "string",
            "example": "Light, heat and power",
            "description": "The accountant’s name."
          },
          "ownerName": {
            "type": "string",
            "example": "Gas and electricity",
            "description": "What owners see."
          },
          "ownerCategory": {
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksOwnerCategory"
              }
            ]
          },
          "ownerCategoryLabel": {
            "type": "string",
            "example": "Premises"
          },
          "hint": {
            "type": [
              "string",
              "null"
            ],
            "description": "One sentence for owners on what goes here."
          },
          "class": {
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksAccountClass"
              }
            ]
          },
          "normalBalance": {
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksNormalBalance"
              }
            ]
          },
          "subtype": {
            "type": "string",
            "example": "overhead"
          },
          "leadLine": {
            "type": [
              "string",
              "null"
            ],
            "example": "M.adm",
            "description": "The Working Papers lead schedule line the account maps to."
          },
          "sa103": {
            "type": [
              "string",
              "null"
            ],
            "description": "The SA103 line (sole traders)."
          },
          "systemRole": {
            "type": [
              "string",
              "null"
            ],
            "description": "Set for accounts Tolvi keeps (control accounts, suspense, retained earnings or capital): they can’t be archived or take a manual journal."
          },
          "defaultVatCodeId": {
            "type": [
              "string",
              "null"
            ],
            "example": "S20",
            "description": "The VAT code suggested for new lines."
          },
          "fromTemplate": {
            "type": "boolean",
            "description": "Created from the chart template when the business signed up."
          },
          "archived": {
            "type": "boolean"
          },
          "archivedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "used": {
            "type": "boolean",
            "description": "Posted to at least once: it can then be archived, never deleted."
          },
          "balancePence": {
            "type": "integer",
            "description": "The balance now, in pence (debit positive, credit negative)."
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "description": "An account in the business’s chart of accounts. Owners see `ownerName` under `ownerCategoryLabel`; accountants see the code, name and class.",
        "required": [
          "id",
          "code",
          "name",
          "ownerName",
          "ownerCategory",
          "ownerCategoryLabel",
          "hint",
          "class",
          "normalBalance",
          "subtype",
          "leadLine",
          "sa103",
          "systemRole",
          "defaultVatCodeId",
          "fromTemplate",
          "archived",
          "archivedAt",
          "used",
          "balancePence",
          "createdAt",
          "updatedAt"
        ]
      },
      "BooksChartOfAccounts": {
        "type": "object",
        "properties": {
          "templateId": {
            "type": "string",
            "example": "ltd_frs102_1a"
          },
          "templateVersion": {
            "type": "string",
            "example": "2026-11"
          },
          "entityType": {
            "type": "string",
            "example": "LTD_FRS102_1A"
          },
          "accounts": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BooksAccount"
            }
          }
        },
        "description": "The business’s chart of accounts, and the template version it started from.",
        "required": [
          "templateId",
          "templateVersion",
          "entityType",
          "accounts"
        ]
      },
      "BooksCreateAccount": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "maxLength": 120,
            "example": "Software subscriptions"
          },
          "ownerName": {
            "type": "string",
            "maxLength": 120,
            "description": "What owners see; defaults to the name."
          },
          "ownerCategory": {
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksOwnerCategory"
              }
            ]
          },
          "class": {
            "description": "Needed only where a category spans classes (bank and cash, tax, you and the business).",
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksAccountClass"
              }
            ]
          },
          "code": {
            "type": "string",
            "maxLength": 20,
            "description": "Defaults to the next free code in the category’s range."
          },
          "leadLine": {
            "type": "string",
            "description": "Working Papers lead schedule line (accountants)."
          },
          "sa103": {
            "type": "string",
            "description": "SA103 line (accountants, sole traders)."
          },
          "subtype": {
            "type": "string"
          },
          "hint": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 300
          },
          "defaultVatCodeId": {
            "type": [
              "string",
              "null"
            ],
            "example": "S20"
          },
          "likeAccountId": {
            "type": "string",
            "format": "uuid",
            "description": "Copy the mapping from this account."
          }
        },
        "description": "Add an account. Give a name and a category; Tolvi picks a free code and copies the mapping from a similar account unless you say otherwise.",
        "required": [
          "name",
          "ownerCategory"
        ]
      },
      "BooksUpdateAccount": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "maxLength": 120
          },
          "ownerName": {
            "type": "string",
            "maxLength": 120
          },
          "ownerCategory": {
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksOwnerCategory"
              }
            ]
          },
          "hint": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 300
          },
          "defaultVatCodeId": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "description": "Rename or recategorise an account. Codes and classes never change."
      },
      "BooksEntryKind": {
        "type": "string",
        "enum": [
          "bank",
          "invoice",
          "credit_note",
          "bill",
          "bill_credit",
          "receipt",
          "expense_claim",
          "journal",
          "opening",
          "reversal",
          "year_end_adjustment",
          "vat_settlement",
          "fx_revaluation"
        ]
      },
      "BooksPostedVia": {
        "type": "string",
        "enum": [
          "web",
          "api",
          "mcp",
          "bank_rule",
          "ai_accepted",
          "import",
          "system"
        ]
      },
      "BooksAccountLedgerLine": {
        "type": "object",
        "properties": {
          "entryId": {
            "type": "string",
            "format": "uuid"
          },
          "seq": {
            "type": "integer"
          },
          "lineIndex": {
            "type": "integer"
          },
          "date": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "kind": {
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksEntryKind"
              }
            ]
          },
          "description": {
            "type": "string"
          },
          "amountPence": {
            "type": "integer",
            "description": "Debit positive, credit negative."
          },
          "runningBalancePence": {
            "type": "integer"
          },
          "via": {
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksPostedVia"
              }
            ]
          }
        },
        "required": [
          "entryId",
          "seq",
          "lineIndex",
          "date",
          "kind",
          "description",
          "amountPence",
          "runningBalancePence",
          "via"
        ]
      },
      "BooksAccountLedger": {
        "type": "object",
        "properties": {
          "account": {
            "$ref": "#/components/schemas/BooksAccount"
          },
          "from": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "to": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "openingPence": {
            "type": "integer"
          },
          "closingPence": {
            "type": "integer"
          },
          "lines": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BooksAccountLedgerLine"
            }
          }
        },
        "description": "One account’s postings between two dates, with the balance brought forward and a running balance.",
        "required": [
          "account",
          "from",
          "to",
          "openingPence",
          "closingPence",
          "lines"
        ]
      },
      "BooksEntrySource": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "example": "journal"
          },
          "id": {
            "type": "string"
          },
          "key": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "type",
          "id",
          "key"
        ]
      },
      "BooksActorKind": {
        "type": "string",
        "enum": [
          "person",
          "rule",
          "link",
          "system"
        ]
      },
      "BooksActor": {
        "type": "object",
        "properties": {
          "kind": {
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksActorKind"
              }
            ]
          },
          "id": {
            "type": "string"
          },
          "version": {
            "type": [
              "integer",
              "null"
            ]
          }
        },
        "required": [
          "kind",
          "id",
          "version"
        ]
      },
      "BooksVatSide": {
        "type": "string",
        "enum": [
          "sale",
          "purchase"
        ]
      },
      "BooksVatBoxContribution": {
        "type": "object",
        "properties": {
          "box": {
            "type": "integer",
            "example": 1
          },
          "amountPence": {
            "type": "integer"
          }
        },
        "required": [
          "box",
          "amountPence"
        ]
      },
      "BooksLineVat": {
        "type": "object",
        "properties": {
          "vatCodeId": {
            "type": "string",
            "example": "S20"
          },
          "side": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/BooksVatSide"
              },
              {
                "type": "null"
              }
            ]
          },
          "netPence": {
            "type": "integer"
          },
          "vatPence": {
            "type": "integer"
          },
          "rateVersion": {
            "type": [
              "string",
              "null"
            ],
            "example": "S20@2011-01-04"
          },
          "taxPoint": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31",
            "description": "When it differs from the entry’s."
          },
          "cashBasisDate": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31"
          },
          "boxes": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BooksVatBoxContribution"
            }
          },
          "capitalGoods": {
            "type": [
              "boolean",
              "null"
            ]
          },
          "frsRelevantGoods": {
            "type": [
              "boolean",
              "null"
            ]
          },
          "frsOutsideScheme": {
            "type": [
              "boolean",
              "null"
            ]
          }
        },
        "description": "VAT on a posted line, worked once at posting and never recomputed.",
        "required": [
          "vatCodeId",
          "side",
          "netPence",
          "vatPence",
          "rateVersion",
          "taxPoint",
          "cashBasisDate",
          "boxes",
          "capitalGoods",
          "frsRelevantGoods",
          "frsOutsideScheme"
        ]
      },
      "BooksEntryLine": {
        "type": "object",
        "properties": {
          "lineIndex": {
            "type": "integer"
          },
          "accountId": {
            "type": "string",
            "format": "uuid"
          },
          "accountCode": {
            "type": "string"
          },
          "accountName": {
            "type": "string"
          },
          "accountOwnerName": {
            "type": "string"
          },
          "amountPence": {
            "type": "integer",
            "description": "Debit positive, credit negative."
          },
          "description": {
            "type": [
              "string",
              "null"
            ]
          },
          "contactId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "vat": {
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksLineVat"
              }
            ]
          }
        },
        "required": [
          "lineIndex",
          "accountId",
          "accountCode",
          "accountName",
          "accountOwnerName",
          "amountPence",
          "description",
          "contactId",
          "vat"
        ]
      },
      "BooksEntry": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "seq": {
            "type": "integer",
            "description": "Numbered from 1 per business, without gaps."
          },
          "kind": {
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksEntryKind"
              }
            ]
          },
          "date": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "taxPoint": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31"
          },
          "description": {
            "type": "string"
          },
          "source": {
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksEntrySource"
              }
            ]
          },
          "reversesSeq": {
            "type": [
              "integer",
              "null"
            ]
          },
          "reversedBySeq": {
            "type": [
              "integer",
              "null"
            ],
            "description": "The entry that reversed this one."
          },
          "postedAt": {
            "type": "string",
            "format": "date-time"
          },
          "postedBy": {
            "$ref": "#/components/schemas/BooksActor"
          },
          "via": {
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksPostedVia"
              }
            ]
          },
          "actingFirmId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid",
            "description": "The practice that posted it through its link."
          },
          "practiceLinkId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "prevHash": {
            "type": [
              "string",
              "null"
            ]
          },
          "hash": {
            "type": "string",
            "example": "sha256:…"
          },
          "journalId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid",
            "description": "The manual journal it posted from."
          },
          "lines": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BooksEntryLine"
            }
          }
        },
        "description": "A posted entry. Posted entries never change: a correction is a reversal and a new entry. `hash` chains each entry to the one before.",
        "required": [
          "id",
          "seq",
          "kind",
          "date",
          "taxPoint",
          "description",
          "source",
          "reversesSeq",
          "reversedBySeq",
          "postedAt",
          "postedBy",
          "via",
          "actingFirmId",
          "practiceLinkId",
          "prevHash",
          "hash",
          "journalId",
          "lines"
        ]
      },
      "BooksEntryPage": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BooksEntry"
            }
          },
          "nextBeforeSeq": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Pass as beforeSeq for the next (older) page; null on the last page."
          }
        },
        "required": [
          "items",
          "nextBeforeSeq"
        ]
      },
      "BooksReverseEntry": {
        "type": "object",
        "properties": {
          "date": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31",
            "description": "Defaults to the original’s date, or the first open day after it."
          },
          "description": {
            "type": "string",
            "maxLength": 500
          }
        },
        "description": "Reverse an opening balances entry or an adjustment that isn’t a journal’s (void a journal instead)."
      },
      "BooksJournalStatus": {
        "type": "string",
        "enum": [
          "draft",
          "posted",
          "voided"
        ]
      },
      "BooksJournalKind": {
        "type": "string",
        "enum": [
          "journal",
          "year_end_adjustment"
        ]
      },
      "BooksJournalLineVat": {
        "type": "object",
        "properties": {
          "vatCodeId": {
            "type": "string",
            "example": "S20"
          },
          "side": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/BooksVatSide"
              },
              {
                "type": "null"
              }
            ]
          },
          "netPence": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Defaults to the line’s amount."
          },
          "vatPence": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Worked from the rate when left out."
          },
          "taxPoint": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31"
          },
          "capitalGoods": {
            "type": [
              "boolean",
              "null"
            ]
          },
          "frsRelevantGoods": {
            "type": [
              "boolean",
              "null"
            ]
          },
          "frsOutsideScheme": {
            "type": [
              "boolean",
              "null"
            ]
          },
          "workedVatPence": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Read only: the VAT as posting would work it."
          }
        },
        "required": [
          "vatCodeId"
        ]
      },
      "BooksJournalLine": {
        "type": "object",
        "properties": {
          "accountId": {
            "type": "string",
            "format": "uuid"
          },
          "amountPence": {
            "type": "integer",
            "description": "Debit positive, credit negative. With VAT, the net."
          },
          "description": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 200
          },
          "vat": {
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksJournalLineVat"
              }
            ]
          }
        },
        "required": [
          "accountId",
          "amountPence"
        ]
      },
      "BooksLedgerProblem": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string",
            "example": "unbalanced"
          },
          "message": {
            "type": "string"
          },
          "line": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Zero-based index of the line it is about."
          }
        },
        "description": "Why something can’t be posted, in plain English.",
        "required": [
          "code",
          "message",
          "line"
        ]
      },
      "BooksJournal": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "status": {
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksJournalStatus"
              }
            ]
          },
          "kind": {
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksJournalKind"
              }
            ]
          },
          "date": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "description": {
            "type": "string"
          },
          "reference": {
            "type": [
              "string",
              "null"
            ]
          },
          "lines": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BooksJournalLine"
            }
          },
          "debitsPence": {
            "type": "integer"
          },
          "creditsPence": {
            "type": "integer",
            "description": "Positive: the sum of the credit lines."
          },
          "vatControlPence": {
            "type": "integer",
            "description": "What Tolvi will post to the VAT account for VAT on the lines (debit positive)."
          },
          "differencePence": {
            "type": "integer",
            "description": "Debits less credits, including the VAT line: nil when it balances."
          },
          "problems": {
            "description": "Why it can’t be posted yet (drafts only).",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BooksLedgerProblem"
            }
          },
          "entryId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "entrySeq": {
            "type": [
              "integer",
              "null"
            ]
          },
          "voidEntryId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "createdBy": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          },
          "postedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "voidedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          }
        },
        "description": "A manual journal. A draft can be edited, discarded or posted; once posted it is changed only by amending it (a reversal and a new entry) or voiding it (a reversal). VAT on lines is posted to the VAT account by Tolvi.",
        "required": [
          "id",
          "status",
          "kind",
          "date",
          "description",
          "reference",
          "lines",
          "debitsPence",
          "creditsPence",
          "vatControlPence",
          "differencePence",
          "problems",
          "entryId",
          "entrySeq",
          "voidEntryId",
          "createdBy",
          "createdAt",
          "updatedAt",
          "postedAt",
          "voidedAt"
        ]
      },
      "BooksCreateJournal": {
        "type": "object",
        "properties": {
          "date": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "description": {
            "type": "string",
            "maxLength": 500
          },
          "reference": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 60
          },
          "kind": {
            "description": "journal (default) or year_end_adjustment.",
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksJournalKind"
              }
            ]
          },
          "lines": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BooksJournalLine"
            }
          }
        },
        "required": [
          "date"
        ]
      },
      "BooksUpdateJournal": {
        "type": "object",
        "properties": {
          "date": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "description": {
            "type": "string",
            "maxLength": 500
          },
          "reference": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 60
          },
          "kind": {
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksJournalKind"
              }
            ]
          },
          "lines": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BooksJournalLine"
            }
          }
        },
        "description": "Change a draft. Only the fields sent change; `lines` replaces every line."
      },
      "BooksVoidJournal": {
        "type": "object",
        "properties": {
          "date": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31",
            "description": "Defaults to the journal’s date, or the first open day after it."
          }
        }
      },
      "BooksAmendJournal": {
        "type": "object",
        "properties": {
          "date": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "description": {
            "type": "string",
            "maxLength": 500
          },
          "reference": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 60
          },
          "lines": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BooksJournalLine"
            }
          }
        },
        "description": "The journal as it should have been. Tolvi reverses the posted entry and posts this, in one step.",
        "required": [
          "date",
          "description",
          "lines"
        ]
      },
      "BooksTrialBalanceRow": {
        "type": "object",
        "properties": {
          "accountId": {
            "type": "string",
            "format": "uuid"
          },
          "code": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "ownerName": {
            "type": "string"
          },
          "ownerCategory": {
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksOwnerCategory"
              }
            ]
          },
          "ownerCategoryLabel": {
            "type": "string"
          },
          "class": {
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksAccountClass"
              }
            ]
          },
          "normalBalance": {
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksNormalBalance"
              }
            ]
          },
          "leadLine": {
            "type": [
              "string",
              "null"
            ]
          },
          "balancePence": {
            "type": "integer",
            "description": "Debit positive, credit negative."
          }
        },
        "required": [
          "accountId",
          "code",
          "name",
          "ownerName",
          "ownerCategory",
          "ownerCategoryLabel",
          "class",
          "normalBalance",
          "leadLine",
          "balancePence"
        ]
      },
      "BooksTrialBalance": {
        "type": "object",
        "properties": {
          "asAt": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "yearStart": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "throughSeq": {
            "type": "integer"
          },
          "ledgerHash": {
            "type": [
              "string",
              "null"
            ]
          },
          "rows": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BooksTrialBalanceRow"
            }
          },
          "totalDebitsPence": {
            "type": "integer"
          },
          "totalCreditsPence": {
            "type": "integer",
            "description": "Positive: the sum of credit balances."
          }
        },
        "description": "The trial balance at a date, derived from posted entries (nothing is stored). Profit and loss before the year start is in retained earnings or the capital account. `throughSeq` and `ledgerHash` pin exactly which entries it reflects.",
        "required": [
          "asAt",
          "yearStart",
          "throughSeq",
          "ledgerHash",
          "rows",
          "totalDebitsPence",
          "totalCreditsPence"
        ]
      },
      "BooksLedgerChange": {
        "type": "object",
        "properties": {
          "entryId": {
            "type": "string",
            "format": "uuid"
          },
          "seq": {
            "type": "integer"
          },
          "lineIndex": {
            "type": "integer"
          },
          "accountId": {
            "type": "string",
            "format": "uuid"
          },
          "accountCode": {
            "type": "string"
          },
          "date": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "description": {
            "type": "string"
          },
          "amountPence": {
            "type": "integer"
          },
          "postedAt": {
            "type": "string",
            "format": "date-time"
          },
          "kind": {
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksEntryKind"
              }
            ]
          },
          "via": {
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksPostedVia"
              }
            ]
          }
        },
        "required": [
          "entryId",
          "seq",
          "lineIndex",
          "accountId",
          "accountCode",
          "date",
          "description",
          "amountPence",
          "postedAt",
          "kind",
          "via"
        ]
      },
      "BooksLedgerChanges": {
        "type": "object",
        "properties": {
          "throughSeq": {
            "type": "integer"
          },
          "asAt": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "headSeq": {
            "type": "integer",
            "description": "The latest entry now."
          },
          "changes": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BooksLedgerChange"
            }
          }
        },
        "description": "Postings made after a ledger point (`throughSeq`) that change a balance on or before `asAt`: what explains a difference since a trial balance was taken.",
        "required": [
          "throughSeq",
          "asAt",
          "headSeq",
          "changes"
        ]
      },
      "BooksIntegrityProblemKind": {
        "type": "string",
        "enum": [
          "sequence_gap",
          "prev_hash_mismatch",
          "hash_mismatch",
          "unbalanced"
        ]
      },
      "BooksLedgerIntegrityProblem": {
        "type": "object",
        "properties": {
          "seq": {
            "type": "integer"
          },
          "kind": {
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksIntegrityProblemKind"
              }
            ]
          },
          "message": {
            "type": "string"
          }
        },
        "required": [
          "seq",
          "kind",
          "message"
        ]
      },
      "BooksLedgerIntegrity": {
        "type": "object",
        "properties": {
          "ok": {
            "type": "boolean"
          },
          "entries": {
            "type": "integer"
          },
          "headSeq": {
            "type": "integer"
          },
          "headHash": {
            "type": [
              "string",
              "null"
            ]
          },
          "problem": {
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksLedgerIntegrityProblem"
              }
            ]
          }
        },
        "description": "The hash chain re-walked from the first entry: numbering without gaps, each entry unchanged since posting and balanced.",
        "required": [
          "ok",
          "entries",
          "headSeq",
          "headHash",
          "problem"
        ]
      },
      "BooksLockBy": {
        "type": "string",
        "enum": [
          "owner",
          "practice",
          "system"
        ]
      },
      "BooksLockState": {
        "type": "object",
        "properties": {
          "through": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31",
            "description": "Nothing new may be dated on or before this day."
          },
          "at": {
            "type": "string",
            "format": "date-time"
          },
          "byKind": {
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksLockBy"
              }
            ]
          },
          "byName": {
            "type": [
              "string",
              "null"
            ],
            "description": "The practice’s name, for an accountant’s lock."
          },
          "linkId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "reference": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "through",
          "at",
          "byKind",
          "byName",
          "linkId",
          "reference"
        ]
      },
      "BooksLockKind": {
        "type": "string",
        "enum": [
          "owner",
          "vat_filed",
          "accountant"
        ]
      },
      "BooksLockAction": {
        "type": "string",
        "enum": [
          "lock",
          "unlock"
        ]
      },
      "BooksLockEvent": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "kind": {
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksLockKind"
              }
            ]
          },
          "action": {
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksLockAction"
              }
            ]
          },
          "through": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31"
          },
          "at": {
            "type": "string",
            "format": "date-time"
          },
          "byKind": {
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksLockBy"
              }
            ]
          },
          "byName": {
            "type": [
              "string",
              "null"
            ]
          },
          "byUserId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "linkId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "reason": {
            "type": [
              "string",
              "null"
            ]
          },
          "reference": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "id",
          "kind",
          "action",
          "through",
          "at",
          "byKind",
          "byName",
          "byUserId",
          "linkId",
          "reason",
          "reference"
        ]
      },
      "BooksLocks": {
        "type": "object",
        "properties": {
          "owner": {
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksLockState"
              }
            ]
          },
          "accountant": {
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksLockState"
              }
            ]
          },
          "vatFiled": {
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksLockState"
              }
            ]
          },
          "firstOpenDate": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "date": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "dateProblem": {
            "type": [
              "string",
              "null"
            ]
          },
          "events": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BooksLockEvent"
            }
          }
        },
        "description": "The locks in force. owner: the business closed its books to a date (it or its practice can move it). accountant: the practice locked them after year-end sign-off (only it can reopen them). vatFiled: set by Tolvi when HMRC accepts a VAT return; never lifted.",
        "required": [
          "owner",
          "accountant",
          "vatFiled",
          "firstOpenDate",
          "date",
          "dateProblem",
          "events"
        ]
      },
      "BooksPersonLockKind": {
        "type": "string",
        "enum": [
          "owner",
          "accountant"
        ],
        "description": "owner: the business’s own lock. accountant: the practice’s year-end lock (practices only)."
      },
      "BooksChangeLock": {
        "type": "object",
        "properties": {
          "kind": {
            "description": "owner: the business’s own lock. accountant: the practice’s year-end lock (practices only).",
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksPersonLockKind"
              }
            ]
          },
          "action": {
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksLockAction"
              }
            ]
          },
          "through": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31"
          },
          "reason": {
            "type": "string",
            "maxLength": 500,
            "description": "Needed to reopen a year the accountant locked."
          },
          "reference": {
            "type": "string",
            "maxLength": 100,
            "description": "e.g. the engagement behind a year-end lock."
          }
        },
        "description": "Lock the books through a date, or move a lock back (with `through`) or lift it (no `through`).",
        "required": [
          "kind",
          "action"
        ]
      },
      "BooksOpeningStandingInvoice": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "number": {
            "type": "string"
          },
          "customerName": {
            "type": "string"
          },
          "amountPence": {
            "type": "integer"
          },
          "outstandingPence": {
            "type": "integer"
          }
        },
        "required": [
          "id",
          "number",
          "customerName",
          "amountPence",
          "outstandingPence"
        ]
      },
      "BooksOpeningStandingBill": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "reference": {
            "type": "string"
          },
          "supplierName": {
            "type": "string"
          },
          "amountPence": {
            "type": "integer"
          },
          "outstandingPence": {
            "type": "integer"
          }
        },
        "required": [
          "id",
          "reference",
          "supplierName",
          "amountPence",
          "outstandingPence"
        ]
      },
      "BooksOpeningStanding": {
        "type": "object",
        "properties": {
          "entryId": {
            "type": "string",
            "format": "uuid"
          },
          "seq": {
            "type": "integer"
          },
          "entryDate": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "startDate": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31",
            "description": "The first day the books cover."
          },
          "fromWorkingPapers": {
            "type": "boolean",
            "description": "Posted from a final trial balance in Working Papers."
          },
          "postedAt": {
            "type": "string",
            "format": "date-time"
          },
          "lines": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BooksOpeningEntryLine"
            }
          },
          "suspensePence": {
            "type": "integer"
          },
          "unpaidInvoices": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BooksOpeningStandingInvoice"
            }
          },
          "unpaidBills": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BooksOpeningStandingBill"
            }
          }
        },
        "description": "The opening entry in force.",
        "required": [
          "entryId",
          "seq",
          "entryDate",
          "startDate",
          "fromWorkingPapers",
          "postedAt",
          "lines",
          "suspensePence",
          "unpaidInvoices",
          "unpaidBills"
        ]
      },
      "BooksOpeningGuidedAccounts": {
        "type": "object",
        "properties": {
          "bank": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BooksOpeningAccountRef"
            }
          },
          "debtors": {
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksOpeningAccountRef"
              }
            ]
          },
          "creditors": {
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksOpeningAccountRef"
              }
            ]
          },
          "vat": {
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksOpeningAccountRef"
              }
            ]
          },
          "loan": {
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksOpeningAccountRef"
              }
            ]
          },
          "worth": {
            "description": "Where the difference goes when it is what the business was worth.",
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksOpeningAccountRef"
              }
            ]
          }
        },
        "description": "The accounts each plain-English question posts to.",
        "required": [
          "bank",
          "debtors",
          "creditors",
          "vat",
          "loan",
          "worth"
        ]
      },
      "BooksOpeningStatus": {
        "type": "object",
        "properties": {
          "suggestedStartDate": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31",
            "description": "The first day of this financial year."
          },
          "standing": {
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksOpeningStanding"
              }
            ]
          },
          "guided": {
            "$ref": "#/components/schemas/BooksOpeningGuidedAccounts"
          },
          "vatRegistered": {
            "type": "boolean"
          },
          "vatScheme": {
            "type": [
              "string",
              "null"
            ]
          },
          "canSetUp": {
            "type": "boolean",
            "description": "This person can post and reverse opening balances."
          }
        },
        "description": "Whether the books have a start, and what the opening balances screen needs.",
        "required": [
          "suggestedStartDate",
          "standing",
          "guided",
          "vatRegistered",
          "vatScheme",
          "canSetUp"
        ]
      },
      "BooksOpeningDifferenceTo": {
        "type": "string",
        "enum": [
          "suspense",
          "equity"
        ],
        "description": "suspense (the default): a difference is an error for the accountant to clear. equity: it is what the business was worth (capital or reserves)."
      },
      "BooksOpeningUnpaidInvoiceInput": {
        "type": "object",
        "properties": {
          "customerId": {
            "type": "string",
            "format": "uuid"
          },
          "customerName": {
            "type": "string",
            "maxLength": 200
          },
          "number": {
            "type": "string",
            "maxLength": 60,
            "description": "The number it was issued with, outside Tolvi’s own series."
          },
          "issueDate": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "dueDate": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31",
            "description": "Defaults to the business’s usual payment terms."
          },
          "amountPence": {
            "type": "integer",
            "description": "What is still owed, including any VAT."
          }
        },
        "description": "An invoice issued before the books start and not yet paid. Name the customer by id, or by name to find or add them.",
        "required": [
          "number",
          "issueDate",
          "amountPence"
        ]
      },
      "BooksOpeningUnpaidBillInput": {
        "type": "object",
        "properties": {
          "supplierId": {
            "type": "string",
            "format": "uuid"
          },
          "supplierName": {
            "type": "string",
            "maxLength": 200
          },
          "reference": {
            "type": "string",
            "maxLength": 60,
            "description": "The supplier’s own invoice number."
          },
          "billDate": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "dueDate": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31",
            "description": "Defaults to the supplier’s payment terms, or 30 days."
          },
          "amountPence": {
            "type": "integer",
            "description": "What is still owed, including any VAT."
          }
        },
        "description": "A bill dated before the books start and not yet paid. Name the supplier by id, or by name to find or add them.",
        "required": [
          "reference",
          "billDate",
          "amountPence"
        ]
      },
      "BooksOpeningBalancesInput": {
        "type": "object",
        "properties": {
          "conversionDate": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31",
            "description": "The first day the books cover; the entry is dated the day before."
          },
          "accounts": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "code",
                "balancePence"
              ],
              "properties": {
                "code": {
                  "type": "string"
                },
                "name": {
                  "type": "string"
                },
                "balancePence": {
                  "type": "integer",
                  "description": "Debit positive, credit negative."
                },
                "leadLine": {
                  "type": [
                    "string",
                    "null"
                  ]
                }
              }
            }
          },
          "csv": {
            "type": "string",
            "description": "A trial balance export as CSV text (code, name, debit, credit or balance)."
          },
          "mapping": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            },
            "description": "Source code to an account code in these books."
          },
          "differenceTo": {
            "description": "suspense (the default): a difference is an error for the accountant to clear. equity: it is what the business was worth (capital or reserves).",
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksOpeningDifferenceTo"
              }
            ]
          },
          "unpaidInvoices": {
            "description": "Invoices issued before the books start and not yet paid. They are part of the debtors balance and can be paid and chased like any other.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BooksOpeningUnpaidInvoiceInput"
            }
          },
          "unpaidBills": {
            "description": "Bills dated before the books start and not yet paid. They are part of the creditors balance and can be paid and matched like any other, with no VAT breakdown.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BooksOpeningUnpaidBillInput"
            }
          }
        },
        "description": "Opening balances from a trial balance (as accounts, or the CSV text of an export), at the date the books start.",
        "required": [
          "conversionDate"
        ]
      },
      "BooksOpeningUnpaidInvoice": {
        "type": "object",
        "properties": {
          "customerName": {
            "type": "string"
          },
          "newCustomer": {
            "type": "boolean",
            "description": "The customer will be added."
          },
          "number": {
            "type": "string"
          },
          "issueDate": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "dueDate": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "amountPence": {
            "type": "integer"
          }
        },
        "required": [
          "customerName",
          "newCustomer",
          "number",
          "issueDate",
          "dueDate",
          "amountPence"
        ]
      },
      "BooksOpeningUnpaidBill": {
        "type": "object",
        "properties": {
          "supplierName": {
            "type": "string"
          },
          "newSupplier": {
            "type": "boolean",
            "description": "The supplier will be added."
          },
          "reference": {
            "type": "string"
          },
          "billDate": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "dueDate": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "amountPence": {
            "type": "integer"
          }
        },
        "required": [
          "supplierName",
          "newSupplier",
          "reference",
          "billDate",
          "dueDate",
          "amountPence"
        ]
      },
      "BooksOpeningBalancesPreview": {
        "type": "object",
        "properties": {
          "conversionDate": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "entryDate": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "plan": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BooksOpeningPlanLine"
            }
          },
          "unmapped": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BooksOpeningUnmapped"
            }
          },
          "lines": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BooksOpeningEntryLine"
            }
          },
          "suspensePence": {
            "type": "integer",
            "description": "What went to suspense to make it balance (debit positive)."
          },
          "equityPence": {
            "type": "integer",
            "description": "What went to capital or reserves to make it balance (debit positive)."
          },
          "warnings": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "problems": {
            "description": "What stops it being posted, in words.",
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "unpaidInvoices": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BooksOpeningUnpaidInvoice"
            }
          },
          "unpaidBills": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BooksOpeningUnpaidBill"
            }
          },
          "alreadyPosted": {
            "type": "boolean"
          }
        },
        "description": "Where each balance would go, the entry that would be posted, and anything that must be mapped first.",
        "required": [
          "conversionDate",
          "entryDate",
          "plan",
          "unmapped",
          "lines",
          "suspensePence",
          "equityPence",
          "warnings",
          "problems",
          "unpaidInvoices",
          "unpaidBills",
          "alreadyPosted"
        ]
      },
      "BooksOpeningBalancesPosted": {
        "type": "object",
        "properties": {
          "entry": {
            "$ref": "#/components/schemas/BooksEntry"
          },
          "suspensePence": {
            "type": "integer"
          },
          "warnings": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        },
        "required": [
          "entry",
          "suspensePence",
          "warnings"
        ]
      },
      "ReceiptSource": {
        "type": "string",
        "enum": [
          "camera",
          "upload",
          "email"
        ]
      },
      "ReceiptFileStatus": {
        "type": "string",
        "enum": [
          "pending_upload",
          "pending_scan",
          "available",
          "rejected"
        ],
        "description": "pending_upload, pending_scan (being checked for viruses), available, or rejected (with the reason)."
      },
      "ReceiptReadingStatus": {
        "type": "string",
        "enum": [
          "waiting",
          "queued",
          "reading",
          "done",
          "failed"
        ],
        "description": "waiting (until the virus check passes), queued, reading, done or failed."
      },
      "ReceiptDocumentType": {
        "type": "string",
        "enum": [
          "till_receipt",
          "simplified_vat_invoice",
          "vat_invoice",
          "order_confirmation",
          "statement",
          "not_a_receipt",
          "other"
        ]
      },
      "ReceiptVatRow": {
        "type": "object",
        "properties": {
          "rateBps": {
            "type": "integer",
            "description": "VAT rate in basis points (2000 = 20%)."
          },
          "netPence": {
            "type": [
              "integer",
              "null"
            ]
          },
          "vatPence": {
            "type": "integer"
          }
        },
        "required": [
          "rateBps",
          "netPence",
          "vatPence"
        ]
      },
      "ReceiptLineItem": {
        "type": "object",
        "properties": {
          "description": {
            "type": "string"
          },
          "quantity": {
            "type": [
              "string",
              "null"
            ]
          },
          "amountPence": {
            "type": "integer"
          },
          "vatRateBps": {
            "type": [
              "integer",
              "null"
            ]
          },
          "vatPence": {
            "type": [
              "integer",
              "null"
            ],
            "description": "The VAT shown on this line. Absent on a reading from before lines were captured."
          },
          "accountCode": {
            "type": [
              "string",
              "null"
            ],
            "description": "The category Tolvi AI suggests, from the chart of accounts."
          },
          "confidence": {
            "type": "integer",
            "minimum": 0,
            "maximum": 100,
            "description": "How sure Tolvi AI is of this line, from 0 to 100."
          },
          "reason": {
            "type": [
              "string",
              "null"
            ],
            "description": "Why it is unsure, when it is; otherwise empty."
          }
        },
        "required": [
          "description",
          "quantity",
          "amountPence",
          "vatRateBps"
        ]
      },
      "ReceiptPaymentMethod": {
        "type": "string",
        "enum": [
          "card",
          "cash",
          "bank_transfer",
          "direct_debit",
          "other",
          "unknown"
        ]
      },
      "ReceiptConfidence": {
        "type": "string",
        "enum": [
          "high",
          "medium",
          "low"
        ]
      },
      "ReceiptFieldNote": {
        "type": "object",
        "properties": {
          "confidence": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ReceiptConfidence"
              }
            ]
          },
          "reason": {
            "type": "string"
          },
          "alternative": {
            "type": [
              "string",
              "null"
            ],
            "description": "Another reading worth checking, e.g. \"£36.20\"."
          }
        },
        "description": "How sure Tolvi AI is of one field, and why.",
        "required": [
          "confidence",
          "reason",
          "alternative"
        ]
      },
      "ReceiptFieldNotes": {
        "type": "object",
        "properties": {
          "supplierName": {
            "$ref": "#/components/schemas/ReceiptFieldNote"
          },
          "date": {
            "$ref": "#/components/schemas/ReceiptFieldNote"
          },
          "total": {
            "$ref": "#/components/schemas/ReceiptFieldNote"
          },
          "vat": {
            "$ref": "#/components/schemas/ReceiptFieldNote"
          },
          "vatNumber": {
            "$ref": "#/components/schemas/ReceiptFieldNote"
          }
        },
        "required": [
          "supplierName",
          "date",
          "total",
          "vat",
          "vatNumber"
        ]
      },
      "ReceiptReading": {
        "type": "object",
        "properties": {
          "documentType": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ReceiptDocumentType"
              }
            ]
          },
          "supplierName": {
            "type": [
              "string",
              "null"
            ]
          },
          "supplierVatNumber": {
            "type": [
              "string",
              "null"
            ],
            "description": "As printed on the receipt."
          },
          "documentNumber": {
            "type": [
              "string",
              "null"
            ]
          },
          "date": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31"
          },
          "currency": {
            "type": [
              "string",
              "null"
            ],
            "example": "GBP"
          },
          "totalPence": {
            "type": [
              "integer",
              "null"
            ]
          },
          "netPence": {
            "type": [
              "integer",
              "null"
            ]
          },
          "vatPence": {
            "type": [
              "integer",
              "null"
            ]
          },
          "vatBreakdown": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ReceiptVatRow"
            }
          },
          "lineItems": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ReceiptLineItem"
            }
          },
          "moreLines": {
            "type": "boolean",
            "description": "The document has more lines than Tolvi AI kept."
          },
          "paymentMethod": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ReceiptPaymentMethod"
              }
            ]
          },
          "cardLast4": {
            "type": [
              "string",
              "null"
            ],
            "description": "The last four digits of the card only."
          },
          "fields": {
            "$ref": "#/components/schemas/ReceiptFieldNotes"
          },
          "notes": {
            "type": "string"
          },
          "model": {
            "type": "string",
            "description": "The model that read it."
          },
          "promptVersion": {
            "type": "string",
            "example": "extract_receipt@1"
          },
          "readAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "description": "What Tolvi AI read from the receipt: a suggestion for the person to confirm or correct. Money in integer pence.",
        "required": [
          "documentType",
          "supplierName",
          "supplierVatNumber",
          "documentNumber",
          "date",
          "currency",
          "totalPence",
          "netPence",
          "vatPence",
          "vatBreakdown",
          "lineItems",
          "paymentMethod",
          "cardLast4",
          "fields",
          "notes",
          "model",
          "promptVersion",
          "readAt"
        ]
      },
      "VatCode": {
        "type": "string",
        "enum": [
          "S20",
          "R5",
          "Z0",
          "EX",
          "OS",
          "RC_SERV",
          "DRC_SALE",
          "DRC_SALE_R5",
          "DRC_PURCH",
          "RC_GOODS_SALE",
          "RC_GOODS_PURCH",
          "PIVA",
          "IMPORT_C79",
          "BLOCKED"
        ]
      },
      "ReceiptSuggestedLine": {
        "type": "object",
        "properties": {
          "description": {
            "type": "string"
          },
          "accountCode": {
            "type": [
              "string",
              "null"
            ],
            "description": "The suggested category, from the chart of accounts."
          },
          "grossPence": {
            "type": "integer",
            "description": "What the line cost, including any VAT."
          },
          "vatPence": {
            "type": "integer",
            "description": "The VAT in that cost."
          },
          "vatCode": {
            "allOf": [
              {
                "$ref": "#/components/schemas/VatCode"
              }
            ]
          },
          "checkThis": {
            "type": "boolean",
            "description": "Tolvi AI was barely sure of this line: highlight it for the person to check. It never stops them."
          },
          "checkReason": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "description": "A line of the receipt as Tolvi AI read it, ready to check. Empty for a reading with no line detail or in another currency. Money in integer pence.",
        "required": [
          "description",
          "accountCode",
          "grossPence",
          "vatPence",
          "vatCode",
          "checkThis",
          "checkReason"
        ]
      },
      "ReceiptChecksOf": {
        "type": "string",
        "enum": [
          "reading",
          "confirmed"
        ],
        "description": "Whether these checks are on what Tolvi AI read or on what the person confirmed."
      },
      "ReceiptProblemSeverity": {
        "type": "string",
        "enum": [
          "warning",
          "info"
        ]
      },
      "ReceiptProblem": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string",
            "example": "no_vat_number"
          },
          "severity": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ReceiptProblemSeverity"
              }
            ]
          },
          "field": {
            "type": [
              "string",
              "null"
            ],
            "example": "vatNumber"
          },
          "message": {
            "type": "string"
          },
          "source": {
            "type": [
              "string",
              "null"
            ],
            "description": "The rule behind it."
          }
        },
        "description": "Something to look at before confirming, in plain English.",
        "required": [
          "code",
          "severity",
          "field",
          "message",
          "source"
        ]
      },
      "ReceiptChecks": {
        "type": "object",
        "properties": {
          "of": {
            "description": "Whether these checks are on what Tolvi AI read or on what the person confirmed.",
            "allOf": [
              {
                "$ref": "#/components/schemas/ReceiptChecksOf"
              }
            ]
          },
          "problems": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ReceiptProblem"
            }
          },
          "vatClaimable": {
            "type": "boolean",
            "description": "Whether the VAT on it can be reclaimed: the business is VAT registered and the receipt shows VAT and a valid UK VAT number."
          },
          "suggestedVatCode": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/VatCode"
              },
              {
                "type": "null"
              }
            ]
          },
          "vatNumber": {
            "type": [
              "string",
              "null"
            ],
            "description": "The VAT number without GB, when it passes the check digits."
          }
        },
        "required": [
          "of",
          "problems",
          "vatClaimable",
          "suggestedVatCode",
          "vatNumber"
        ]
      },
      "ReceiptMatchBand": {
        "type": "string",
        "enum": [
          "high",
          "medium",
          "low"
        ]
      },
      "ReceiptMatch": {
        "type": "object",
        "properties": {
          "bankLineId": {
            "type": "string",
            "format": "uuid"
          },
          "bankAccountId": {
            "type": "string",
            "format": "uuid"
          },
          "bookedAt": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "amountPence": {
            "type": "integer",
            "description": "As on the bank line: money out is negative."
          },
          "description": {
            "type": "string"
          },
          "score": {
            "type": "integer",
            "minimum": 0,
            "maximum": 100
          },
          "band": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ReceiptMatchBand"
              }
            ]
          },
          "summary": {
            "type": "string"
          },
          "reasons": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        },
        "description": "A bank payment that could be this receipt, from the matcher, best first.",
        "required": [
          "bankLineId",
          "bankAccountId",
          "bookedAt",
          "amountPence",
          "description",
          "score",
          "band",
          "summary",
          "reasons"
        ]
      },
      "ReceiptReviewStatus": {
        "type": "string",
        "enum": [
          "to_review",
          "confirmed",
          "discarded"
        ]
      },
      "ReceiptConfirmedLine": {
        "type": "object",
        "properties": {
          "description": {
            "type": "string"
          },
          "accountCode": {
            "type": [
              "string",
              "null"
            ]
          },
          "grossPence": {
            "type": "integer",
            "description": "What the line cost, including any VAT."
          },
          "vatPence": {
            "type": "integer"
          }
        },
        "description": "One line as the person confirmed it. Money in integer pence.",
        "required": [
          "description",
          "accountCode",
          "grossPence",
          "vatPence"
        ]
      },
      "ReceiptConfirmed": {
        "type": "object",
        "properties": {
          "supplierName": {
            "type": "string"
          },
          "supplierVatNumber": {
            "type": [
              "string",
              "null"
            ]
          },
          "date": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "currency": {
            "type": "string",
            "example": "GBP"
          },
          "totalPence": {
            "type": "integer"
          },
          "netPence": {
            "type": [
              "integer",
              "null"
            ]
          },
          "vatPence": {
            "type": [
              "integer",
              "null"
            ]
          },
          "vatCode": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/VatCode"
              },
              {
                "type": "null"
              }
            ]
          },
          "accountCode": {
            "type": [
              "string",
              "null"
            ]
          },
          "paymentMethod": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/ReceiptPaymentMethod"
              },
              {
                "type": "null"
              }
            ]
          },
          "cardLast4": {
            "type": [
              "string",
              "null"
            ]
          },
          "paidPersonally": {
            "type": "boolean"
          },
          "bankLineId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "note": {
            "type": [
              "string",
              "null"
            ]
          },
          "correctedFields": {
            "description": "Fields the person changed from what Tolvi AI read; line1.category is the first line’s category.",
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "lines": {
            "description": "The lines it went into the books as. Empty when it was confirmed as one amount.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ReceiptConfirmedLine"
            }
          },
          "confirmedBy": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "confirmedAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "description": "What the person confirmed. Money in integer pence.",
        "required": [
          "supplierName",
          "supplierVatNumber",
          "date",
          "currency",
          "totalPence",
          "netPence",
          "vatPence",
          "vatCode",
          "accountCode",
          "paymentMethod",
          "cardLast4",
          "paidPersonally",
          "bankLineId",
          "note",
          "correctedFields",
          "lines",
          "confirmedBy",
          "confirmedAt"
        ]
      },
      "ReceiptPostingStatus": {
        "type": "string",
        "enum": [
          "none",
          "proposed",
          "posted"
        ],
        "description": "none, proposed (confirmed; waiting for the books), or posted."
      },
      "Receipt": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "source": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ReceiptSource"
              }
            ]
          },
          "fileName": {
            "type": "string"
          },
          "contentType": {
            "type": "string"
          },
          "sizeBytes": {
            "type": "integer"
          },
          "status": {
            "description": "pending_upload, pending_scan (being checked for viruses), available, or rejected (with the reason).",
            "allOf": [
              {
                "$ref": "#/components/schemas/ReceiptFileStatus"
              }
            ]
          },
          "rejectedReason": {
            "type": [
              "string",
              "null"
            ]
          },
          "readingStatus": {
            "description": "waiting (until the virus check passes), queued, reading, done or failed.",
            "allOf": [
              {
                "$ref": "#/components/schemas/ReceiptReadingStatus"
              }
            ]
          },
          "readingError": {
            "type": [
              "string",
              "null"
            ],
            "description": "Why reading failed, in plain English."
          },
          "reading": {
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/ReceiptReading"
              }
            ]
          },
          "suggestedLines": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ReceiptSuggestedLine"
            }
          },
          "checks": {
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/ReceiptChecks"
              }
            ]
          },
          "duplicateOfId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid",
            "description": "An earlier receipt this looks like a copy of."
          },
          "matches": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ReceiptMatch"
            }
          },
          "reviewStatus": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ReceiptReviewStatus"
              }
            ]
          },
          "confirmed": {
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/ReceiptConfirmed"
              }
            ]
          },
          "postingStatus": {
            "description": "none, proposed (confirmed; waiting for the books), or posted.",
            "allOf": [
              {
                "$ref": "#/components/schemas/ReceiptPostingStatus"
              }
            ]
          },
          "postingProposal": {
            "type": [
              "object",
              "null"
            ],
            "additionalProperties": true,
            "description": "What confirming proposes for the books (version 1, or version 2 with lines)."
          },
          "ledgerEntryId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "emailFrom": {
            "type": [
              "string",
              "null"
            ],
            "description": "For an emailed receipt: who sent it."
          },
          "emailSubject": {
            "type": [
              "string",
              "null"
            ]
          },
          "previewable": {
            "type": "boolean",
            "description": "Whether a browser can show the image (a HEIC photo has a JPEG preview once read)."
          },
          "uploadedBy": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "capturedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "description": "A receipt or bill: the file (kept as the record), what Tolvi AI read from it, and what the person confirmed.",
        "required": [
          "id",
          "source",
          "fileName",
          "contentType",
          "sizeBytes",
          "status",
          "rejectedReason",
          "readingStatus",
          "readingError",
          "reading",
          "suggestedLines",
          "checks",
          "duplicateOfId",
          "matches",
          "reviewStatus",
          "confirmed",
          "postingStatus",
          "postingProposal",
          "ledgerEntryId",
          "emailFrom",
          "emailSubject",
          "previewable",
          "uploadedBy",
          "capturedAt",
          "createdAt",
          "updatedAt"
        ]
      },
      "ReceiptList": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Receipt"
            }
          },
          "toReview": {
            "type": "integer",
            "description": "Receipts waiting for the person to check."
          }
        },
        "required": [
          "items",
          "toReview"
        ]
      },
      "ReceiptCaptureSource": {
        "type": "string",
        "enum": [
          "camera",
          "upload"
        ]
      },
      "CreateReceipt": {
        "type": "object",
        "properties": {
          "fileName": {
            "type": "string",
            "maxLength": 200,
            "example": "IMG_2041.HEIC"
          },
          "contentType": {
            "type": "string",
            "example": "image/heic",
            "description": "The type the browser reports; the file name’s extension decides."
          },
          "sizeBytes": {
            "type": "integer",
            "minimum": 1,
            "maximum": 20971520
          },
          "source": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ReceiptCaptureSource"
              }
            ]
          },
          "clientReference": {
            "type": "string",
            "format": "uuid",
            "description": "The app’s own id for this capture: sending it again returns the same receipt (offline retries)."
          },
          "capturedAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "description": "Register a photo or file of a receipt before uploading it.",
        "required": [
          "fileName",
          "sizeBytes"
        ]
      },
      "ReceiptUpload": {
        "type": "object",
        "properties": {
          "receipt": {
            "$ref": "#/components/schemas/Receipt"
          },
          "upload": {
            "description": "PUT the file here with exactly these headers, then call upload-complete. Null when the file has already been uploaded.",
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/PresignedUpload"
              }
            ]
          }
        },
        "required": [
          "receipt",
          "upload"
        ]
      },
      "ReceiptEmailAddress": {
        "type": "object",
        "properties": {
          "address": {
            "type": [
              "string",
              "null"
            ],
            "format": "email",
            "example": "k3v9x2m8q4p7w1z6@receipts.tolvi.co.uk"
          },
          "createdAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          }
        },
        "description": "Where to email receipts in. Anything sent here is read as a receipt for this business.",
        "required": [
          "address",
          "createdAt"
        ]
      },
      "ReceiptImage": {
        "type": "object",
        "properties": {
          "url": {
            "type": "string",
            "format": "uri"
          },
          "contentType": {
            "type": "string"
          },
          "expiresAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "description": "A short-lived link to the receipt’s image (or its JPEG preview for a HEIC photo).",
        "required": [
          "url",
          "contentType",
          "expiresAt"
        ]
      },
      "ConfirmReceiptLine": {
        "type": "object",
        "properties": {
          "description": {
            "type": "string",
            "maxLength": 500
          },
          "accountCode": {
            "type": [
              "string",
              "null"
            ],
            "description": "The account this line goes to. Left out, it is chosen when the bank payment is confirmed, or goes to general costs."
          },
          "grossPence": {
            "type": "integer",
            "description": "What the line cost, including any VAT. A discount is negative."
          },
          "vatPence": {
            "type": [
              "integer",
              "null"
            ],
            "description": "The VAT in that cost. Used only when the VAT can be reclaimed."
          },
          "vatCode": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/VatCode"
              },
              {
                "type": "null"
              }
            ]
          }
        },
        "required": [
          "description",
          "grossPence"
        ]
      },
      "ConfirmReceipt": {
        "type": "object",
        "properties": {
          "supplierName": {
            "type": "string",
            "maxLength": 200
          },
          "supplierVatNumber": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 20
          },
          "date": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "currency": {
            "type": "string",
            "example": "GBP"
          },
          "totalPence": {
            "type": "integer",
            "minimum": 1
          },
          "poundsPence": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 1,
            "description": "What a foreign receipt paid with the person’s own money cost in pounds. Required then; ignored otherwise."
          },
          "netPence": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 0
          },
          "vatPence": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 0
          },
          "vatCode": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/VatCode"
              },
              {
                "type": "null"
              }
            ]
          },
          "accountCode": {
            "type": [
              "string",
              "null"
            ],
            "description": "The account it goes to, from the chart of accounts (or chosen later, when the bank payment is confirmed)."
          },
          "paymentMethod": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/ReceiptPaymentMethod"
              },
              {
                "type": "null"
              }
            ]
          },
          "cardLast4": {
            "type": [
              "string",
              "null"
            ],
            "pattern": "^\\d{4}$"
          },
          "paidPersonally": {
            "type": "boolean",
            "description": "Paid with the owner’s own money: the business owes it back."
          },
          "bankLineId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid",
            "description": "The bank payment it matches, from `matches`."
          },
          "note": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 1000
          },
          "lines": {
            "description": "The lines, each with its own category. They must add up to the total. Ignored for a receipt in another currency, where the amount in pounds comes from the bank payment. Left out, the whole amount is one line.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ConfirmReceiptLine"
            }
          }
        },
        "description": "The person’s figures. Money in integer pence. Net plus VAT must equal the total.",
        "required": [
          "supplierName",
          "date",
          "totalPence"
        ]
      },
      "BooksReportLine": {
        "type": "object",
        "properties": {
          "accountId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "code": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "ownerName": {
            "type": "string"
          },
          "ownerCategory": {
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksOwnerCategory"
              }
            ]
          },
          "currentPence": {
            "type": "integer"
          },
          "comparePence": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Null when no comparison was asked for."
          },
          "drillKey": {
            "type": "string",
            "description": "Pass to the drill-down to list the entries behind this figure."
          }
        },
        "description": "One account in a report. `accountId` is null for a derived line (profit for the period on the balance sheet).",
        "required": [
          "accountId",
          "code",
          "name",
          "ownerName",
          "ownerCategory",
          "currentPence",
          "comparePence",
          "drillKey"
        ]
      },
      "BooksReportSection": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Profit and loss: turnover, cost_of_sales, overheads, other_income, interest, tax. Balance sheet: fixed_assets, current_assets, current_liabilities, long_term_liabilities, unsorted, capital."
          },
          "label": {
            "type": "string"
          },
          "lines": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BooksReportLine"
            }
          },
          "currentPence": {
            "type": "integer"
          },
          "comparePence": {
            "type": [
              "integer",
              "null"
            ]
          },
          "drillKey": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "label",
          "lines",
          "currentPence",
          "comparePence",
          "drillKey"
        ]
      },
      "BooksReportTotal": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Profit and loss: gross_profit, operating_profit, profit_before_tax, net_profit. Balance sheet: net_current_assets, total_assets_less_current_liabilities, net_assets, capital_and_reserves."
          },
          "label": {
            "type": "string"
          },
          "currentPence": {
            "type": "integer"
          },
          "comparePence": {
            "type": [
              "integer",
              "null"
            ]
          },
          "drillKey": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "label",
          "currentPence",
          "comparePence",
          "drillKey"
        ]
      },
      "BooksReportOwnerGroup": {
        "type": "object",
        "properties": {
          "category": {
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksOwnerCategory"
              }
            ]
          },
          "label": {
            "type": "string"
          },
          "lines": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BooksReportLine"
            }
          },
          "currentPence": {
            "type": "integer"
          },
          "comparePence": {
            "type": [
              "integer",
              "null"
            ]
          },
          "drillKey": {
            "type": "string"
          }
        },
        "description": "The same lines grouped by the owner’s plain-English category.",
        "required": [
          "category",
          "label",
          "lines",
          "currentPence",
          "comparePence",
          "drillKey"
        ]
      },
      "BooksProfitAndLossOwnerView": {
        "type": "object",
        "properties": {
          "moneyIn": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BooksReportOwnerGroup"
            }
          },
          "costs": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BooksReportOwnerGroup"
            }
          },
          "moneyInPence": {
            "type": "integer"
          },
          "moneyInComparePence": {
            "type": [
              "integer",
              "null"
            ]
          },
          "costsPence": {
            "type": "integer"
          },
          "costsComparePence": {
            "type": [
              "integer",
              "null"
            ]
          }
        },
        "required": [
          "moneyIn",
          "costs",
          "moneyInPence",
          "moneyInComparePence",
          "costsPence",
          "costsComparePence"
        ]
      },
      "BooksProfitAndLoss": {
        "type": "object",
        "properties": {
          "from": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "to": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "compareFrom": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31"
          },
          "compareTo": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31"
          },
          "throughSeq": {
            "type": "integer",
            "description": "The ledger point the report reflects."
          },
          "sections": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BooksReportSection"
            }
          },
          "totals": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BooksReportTotal"
            }
          },
          "ownerView": {
            "$ref": "#/components/schemas/BooksProfitAndLossOwnerView"
          },
          "netProfitPence": {
            "type": "integer"
          },
          "netProfitComparePence": {
            "type": [
              "integer",
              "null"
            ]
          }
        },
        "description": "Profit and loss for a period, with an optional comparison period (FRS 102 Section 1A layout, grouped by each account’s lead schedule line), and the same figures grouped for owners.",
        "required": [
          "from",
          "to",
          "compareFrom",
          "compareTo",
          "throughSeq",
          "sections",
          "totals",
          "ownerView",
          "netProfitPence",
          "netProfitComparePence"
        ]
      },
      "BooksBalanceSheet": {
        "type": "object",
        "properties": {
          "asAt": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "yearStart": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "compareAsAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31"
          },
          "compareYearStart": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31"
          },
          "throughSeq": {
            "type": "integer"
          },
          "sections": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BooksReportSection"
            }
          },
          "totals": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BooksReportTotal"
            }
          },
          "balanced": {
            "type": "boolean",
            "description": "Net assets equal capital and reserves."
          }
        },
        "description": "What the business owns and owes at a date, with an optional comparison date. Profit for the year so far is a line in capital and reserves.",
        "required": [
          "asAt",
          "yearStart",
          "compareAsAt",
          "compareYearStart",
          "throughSeq",
          "sections",
          "totals",
          "balanced"
        ]
      },
      "BooksAgedSide": {
        "type": "string",
        "enum": [
          "debtors",
          "creditors"
        ]
      },
      "BooksAgedBasis": {
        "type": "string",
        "enum": [
          "documents",
          "ledger"
        ]
      },
      "BooksAgedBuckets": {
        "type": "object",
        "properties": {
          "current": {
            "type": "integer"
          },
          "days_1_30": {
            "type": "integer"
          },
          "days_31_60": {
            "type": "integer"
          },
          "days_61_90": {
            "type": "integer"
          },
          "over_90": {
            "type": "integer"
          }
        },
        "description": "Pence by how overdue: not yet due, 1–30, 31–60, 61–90 and over 90 days.",
        "required": [
          "current",
          "days_1_30",
          "days_31_60",
          "days_61_90",
          "over_90"
        ]
      },
      "BooksAgedBucket": {
        "type": "string",
        "enum": [
          "current",
          "days_1_30",
          "days_31_60",
          "days_61_90",
          "over_90"
        ]
      },
      "BooksAgedItem": {
        "type": "object",
        "properties": {
          "reference": {
            "type": "string"
          },
          "date": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "dueDate": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31"
          },
          "daysOverdue": {
            "type": "integer"
          },
          "bucket": {
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksAgedBucket"
              }
            ]
          },
          "outstandingPence": {
            "type": "integer",
            "description": "Still owed; negative for money paid on account."
          },
          "documentId": {
            "type": [
              "string",
              "null"
            ],
            "description": "The invoice or bill, when worked from documents."
          },
          "entryId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid",
            "description": "The ledger entry, when worked from the ledger."
          }
        },
        "required": [
          "reference",
          "date",
          "dueDate",
          "daysOverdue",
          "bucket",
          "outstandingPence",
          "documentId",
          "entryId"
        ]
      },
      "BooksAgedContact": {
        "type": "object",
        "properties": {
          "contactId": {
            "type": [
              "string",
              "null"
            ]
          },
          "name": {
            "type": "string"
          },
          "buckets": {
            "$ref": "#/components/schemas/BooksAgedBuckets"
          },
          "totalPence": {
            "type": "integer"
          },
          "overduePence": {
            "type": "integer"
          },
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BooksAgedItem"
            }
          }
        },
        "required": [
          "contactId",
          "name",
          "buckets",
          "totalPence",
          "overduePence",
          "items"
        ]
      },
      "BooksAgedReport": {
        "type": "object",
        "properties": {
          "side": {
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksAgedSide"
              }
            ]
          },
          "asAt": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "basis": {
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksAgedBasis"
              }
            ]
          },
          "termsDays": {
            "type": [
              "integer",
              "null"
            ]
          },
          "contacts": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BooksAgedContact"
            }
          },
          "totals": {
            "$ref": "#/components/schemas/BooksAgedBuckets"
          },
          "totalPence": {
            "type": "integer"
          },
          "overduePence": {
            "type": "integer"
          },
          "controlBalancePence": {
            "type": "integer",
            "description": "The control account at `asAt`; owed is positive."
          },
          "differencePence": {
            "type": "integer",
            "description": "Control balance less the aged total (nil on the ledger basis)."
          }
        },
        "description": "Who owes the business (debtors) or whom it owes (creditors), by how overdue. Worked from unpaid invoices and bills where they exist (`basis: documents`), otherwise from the trade debtors or creditors control account by contact, payments set against the oldest amounts first and amounts assumed due `termsDays` after their date (`basis: ledger`). The control account balance is shown beside the total.",
        "required": [
          "side",
          "asAt",
          "basis",
          "termsDays",
          "contacts",
          "totals",
          "totalPence",
          "overduePence",
          "controlBalancePence",
          "differencePence"
        ]
      },
      "BooksVatOwed": {
        "type": "object",
        "properties": {
          "from": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "to": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "accountId": {
            "type": "string",
            "format": "uuid"
          },
          "openingPence": {
            "type": "integer"
          },
          "salesPence": {
            "type": "integer"
          },
          "purchasesPence": {
            "type": "integer",
            "description": "Negative: VAT you can reclaim reduces what is owed."
          },
          "paymentsPence": {
            "type": "integer",
            "description": "Negative for a payment to HMRC."
          },
          "otherPence": {
            "type": "integer"
          },
          "closingPence": {
            "type": "integer"
          }
        },
        "description": "The VAT control account over a period: owed to HMRC at the start, VAT on sales, VAT on purchases, payments to or from HMRC, other adjustments, and owed at the end. Owed to HMRC is positive. This is what the books say; the VAT return is worked from each transaction’s VAT by tax point.",
        "required": [
          "from",
          "to",
          "accountId",
          "openingPence",
          "salesPence",
          "purchasesPence",
          "paymentsPence",
          "otherPence",
          "closingPence"
        ]
      },
      "BooksCashFlowMonth": {
        "type": "object",
        "properties": {
          "month": {
            "type": "string",
            "example": "2026-10"
          },
          "from": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "to": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "inPence": {
            "type": "integer"
          },
          "outPence": {
            "type": "integer"
          },
          "netPence": {
            "type": "integer"
          },
          "closingPence": {
            "type": "integer",
            "description": "Across bank, cash and card accounts at the end of the month."
          }
        },
        "required": [
          "month",
          "from",
          "to",
          "inPence",
          "outPence",
          "netPence",
          "closingPence"
        ]
      },
      "BooksCashFlow": {
        "type": "object",
        "properties": {
          "from": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "to": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "openingPence": {
            "type": "integer"
          },
          "months": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BooksCashFlowMonth"
            }
          },
          "inPence": {
            "type": "integer"
          },
          "outPence": {
            "type": "integer"
          },
          "netPence": {
            "type": "integer"
          },
          "closingPence": {
            "type": "integer"
          }
        },
        "description": "Money in and out of the bank, cash and card accounts, by month. Moving money between the business’s own accounts is neither.",
        "required": [
          "from",
          "to",
          "openingPence",
          "months",
          "inPence",
          "outPence",
          "netPence",
          "closingPence"
        ]
      },
      "BooksSa103Account": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "amountPence": {
            "type": "integer"
          },
          "drillKey": {
            "type": "string",
            "description": "Pass to the drill-down (report profit-and-loss) to list the entries."
          }
        },
        "required": [
          "code",
          "name",
          "amountPence",
          "drillKey"
        ]
      },
      "BooksSa103IncomeBox": {
        "type": "object",
        "properties": {
          "box": {
            "type": "integer"
          },
          "label": {
            "type": "string"
          },
          "amountPence": {
            "type": "integer"
          },
          "accounts": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BooksSa103Account"
            }
          }
        },
        "required": [
          "box",
          "label",
          "amountPence",
          "accounts"
        ]
      },
      "BooksSa103ExpenseBox": {
        "type": "object",
        "properties": {
          "box": {
            "type": "integer"
          },
          "label": {
            "type": "string"
          },
          "amountPence": {
            "type": "integer"
          },
          "accounts": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BooksSa103Account"
            }
          },
          "disallowableBox": {
            "type": "integer"
          },
          "disallowablePence": {
            "type": "integer",
            "description": "The part of this box tax doesn’t allow."
          }
        },
        "required": [
          "box",
          "label",
          "amountPence",
          "accounts",
          "disallowableBox",
          "disallowablePence"
        ]
      },
      "BooksSa103Totals": {
        "type": "object",
        "properties": {
          "from": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "to": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "taxYear": {
            "type": "integer",
            "description": "The tax year, by the year it starts: 2026 is 2026/27."
          },
          "taxYearLabel": {
            "type": "string"
          },
          "source": {
            "type": "string",
            "description": "The HMRC form the box numbers come from."
          },
          "income": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BooksSa103IncomeBox"
            }
          },
          "expenses": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BooksSa103ExpenseBox"
            }
          },
          "totalExpensesBox": {
            "type": "integer"
          },
          "totalExpensesPence": {
            "type": "integer"
          },
          "totalDisallowableBox": {
            "type": "integer"
          },
          "totalDisallowablePence": {
            "type": "integer"
          },
          "netProfitBox": {
            "type": "integer"
          },
          "netLossBox": {
            "type": "integer"
          },
          "netPence": {
            "type": "integer",
            "description": "Income less expenses; negative is a loss."
          },
          "netPounds": {
            "type": "integer",
            "description": "The net figure in whole pounds, rounded down, without a sign."
          },
          "notTrading": {
            "description": "Income left out: it goes on SA100.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BooksSa103Account"
            }
          },
          "unmapped": {
            "description": "Income or cost accounts with no SA103 line.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BooksSa103Account"
            }
          }
        },
        "description": "The income and expense boxes of HMRC’s SA103F for a sole trader, added up from the chart. An aid for the return, never a filing.",
        "required": [
          "from",
          "to",
          "taxYear",
          "taxYearLabel",
          "source",
          "income",
          "expenses",
          "totalExpensesBox",
          "totalExpensesPence",
          "totalDisallowableBox",
          "totalDisallowablePence",
          "netProfitBox",
          "netLossBox",
          "netPence",
          "netPounds",
          "notTrading",
          "unmapped"
        ]
      },
      "BooksDrillReport": {
        "type": "string",
        "enum": [
          "profit-and-loss",
          "balance-sheet"
        ]
      },
      "BooksDrillAccount": {
        "type": "object",
        "properties": {
          "accountId": {
            "type": "string",
            "format": "uuid"
          },
          "code": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "ownerName": {
            "type": "string"
          }
        },
        "required": [
          "accountId",
          "code",
          "name",
          "ownerName"
        ]
      },
      "BooksDrillLine": {
        "type": "object",
        "properties": {
          "entryId": {
            "type": "string",
            "format": "uuid"
          },
          "seq": {
            "type": "integer"
          },
          "lineIndex": {
            "type": "integer"
          },
          "date": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "kind": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "accountId": {
            "type": "string",
            "format": "uuid"
          },
          "accountCode": {
            "type": "string"
          },
          "amountPence": {
            "type": "integer",
            "description": "In the figure’s sense, so the lines add up to it."
          },
          "runningPence": {
            "type": "integer"
          }
        },
        "required": [
          "entryId",
          "seq",
          "lineIndex",
          "date",
          "kind",
          "description",
          "accountId",
          "accountCode",
          "amountPence",
          "runningPence"
        ]
      },
      "BooksDrillDown": {
        "type": "object",
        "properties": {
          "report": {
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksDrillReport"
              }
            ]
          },
          "key": {
            "type": "string"
          },
          "label": {
            "type": "string"
          },
          "from": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "to": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "sense": {
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksNormalBalance"
              }
            ]
          },
          "accounts": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BooksDrillAccount"
            }
          },
          "openingPence": {
            "type": "integer"
          },
          "lines": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BooksDrillLine"
            }
          },
          "closingPence": {
            "type": "integer"
          }
        },
        "description": "The postings behind one report figure. Lines are in the figure’s sense (`sense`), so they add up to it; a balance sheet figure starts from the balance brought forward at the start of the year (including earlier years’ profit in reserves).",
        "required": [
          "report",
          "key",
          "label",
          "from",
          "to",
          "sense",
          "accounts",
          "openingPence",
          "lines",
          "closingPence"
        ]
      },
      "BooksTaxEstimateKind": {
        "type": "string",
        "enum": [
          "sole_trader",
          "company"
        ]
      },
      "BooksTaxWorkingLine": {
        "type": "object",
        "properties": {
          "accountId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "code": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "amountPence": {
            "type": "integer"
          }
        },
        "required": [
          "accountId",
          "code",
          "name",
          "amountPence"
        ]
      },
      "BooksTaxEstimateLineKey": {
        "type": "string",
        "enum": [
          "income_tax",
          "other_income_tax",
          "class4_nic",
          "corporation_tax"
        ],
        "description": "other_income_tax: a sole trader’s tax on their other income less what PAYE took (only when they entered other income)."
      },
      "BooksTaxEstimateLine": {
        "type": "object",
        "properties": {
          "key": {
            "description": "other_income_tax: a sole trader’s tax on their other income less what PAYE took (only when they entered other income).",
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksTaxEstimateLineKey"
              }
            ]
          },
          "label": {
            "type": "string"
          },
          "annualPence": {
            "type": "integer",
            "description": "For the whole year, if profit carries on at the same rate."
          },
          "toDatePence": {
            "type": "integer",
            "description": "The share to have set aside by now."
          }
        },
        "required": [
          "key",
          "label",
          "annualPence",
          "toDatePence"
        ]
      },
      "BooksTaxEstimateBasedOn": {
        "type": "object",
        "properties": {
          "otherIncome": {
            "type": "integer",
            "description": "Sole traders: employment, pensions, property profits and savings interest added up."
          },
          "taxPaidThroughPaye": {
            "type": "integer",
            "description": "Sole traders: tax already taken under PAYE."
          },
          "pensionContributions": {
            "type": "integer",
            "description": "Sole traders: personal pension contributions paid in."
          },
          "directorSalary": {
            "type": "integer",
            "description": "Companies: the director’s planned salary."
          },
          "dividends": {
            "type": "integer",
            "description": "Companies: the director’s planned dividends."
          }
        },
        "description": "The figures the owner entered that the estimate used (pence).",
        "required": [
          "otherIncome",
          "taxPaidThroughPaye",
          "pensionContributions",
          "directorSalary",
          "dividends"
        ]
      },
      "BooksOwnerDividendTax": {
        "type": "object",
        "properties": {
          "taxYear": {
            "type": "integer"
          },
          "taxYearLabel": {
            "type": "string",
            "example": "2026/27"
          },
          "directorSalary": {
            "type": "integer"
          },
          "dividends": {
            "type": "integer"
          },
          "dividendTax": {
            "type": "integer",
            "description": "Income tax on the dividends, after the salary uses the personal allowance and bands first."
          },
          "assumptions": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        },
        "description": "Companies: the director’s own income tax on planned dividends, an estimate. The director pays it, not the company, so it isn’t in the company’s tax to set aside.",
        "required": [
          "taxYear",
          "taxYearLabel",
          "directorSalary",
          "dividends",
          "dividendTax",
          "assumptions"
        ]
      },
      "BooksTaxEstimate": {
        "type": "object",
        "properties": {
          "estimate": {
            "type": "boolean",
            "enum": [
              true
            ]
          },
          "kind": {
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksTaxEstimateKind"
              }
            ]
          },
          "periodFrom": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "periodTo": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "asAt": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "daysElapsed": {
            "type": "integer"
          },
          "daysInPeriod": {
            "type": "integer"
          },
          "profitBeforeTaxPence": {
            "type": "integer"
          },
          "addBacks": {
            "description": "Costs tax doesn’t allow, added back.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BooksTaxWorkingLine"
            }
          },
          "notTrading": {
            "description": "Income that isn’t trading income, taken out (sole traders).",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BooksTaxWorkingLine"
            }
          },
          "profitToDatePence": {
            "type": "integer",
            "description": "Taxable profit so far, whole pounds (floored)."
          },
          "annualisedProfitPence": {
            "type": "integer",
            "description": "For the whole year at the same rate, whole pounds (floored)."
          },
          "taxYearLabel": {
            "type": [
              "string",
              "null"
            ],
            "example": "2026/27"
          },
          "financialYears": {
            "description": "Companies: the financial years whose rates were used.",
            "type": "array",
            "items": {
              "type": "integer"
            }
          },
          "otherIncomePence": {
            "type": "integer"
          },
          "lines": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BooksTaxEstimateLine"
            }
          },
          "annualTaxPence": {
            "type": "integer"
          },
          "setAsideToDatePence": {
            "type": "integer"
          },
          "effectiveRateBps": {
            "type": "integer",
            "description": "Annual tax as a share of annualised profit, basis points."
          },
          "assumptions": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "extraInfoTaxYear": {
            "type": "integer",
            "description": "The tax year the owner’s extra information is for (starting year): the one containing the year end. Use it with /books/tax-details/{taxYear}."
          },
          "extraInfoTaxYearLabel": {
            "type": "string",
            "example": "2026/27"
          },
          "basedOn": {
            "description": "The owner’s extra information used, or null when none was entered.",
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksTaxEstimateBasedOn"
              }
            ]
          },
          "ownerDividendTax": {
            "description": "Companies with planned dividends: the director’s own tax on them.",
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksOwnerDividendTax"
              }
            ]
          }
        },
        "description": "An estimate (never a calculation for filing) of the tax to set aside: income tax and Class 4 National Insurance for a sole trader, corporation tax for a company, on the profit so far annualised over the year. Shows its working and what it assumed.",
        "required": [
          "estimate",
          "kind",
          "periodFrom",
          "periodTo",
          "asAt",
          "daysElapsed",
          "daysInPeriod",
          "profitBeforeTaxPence",
          "addBacks",
          "notTrading",
          "profitToDatePence",
          "annualisedProfitPence",
          "taxYearLabel",
          "financialYears",
          "otherIncomePence",
          "lines",
          "annualTaxPence",
          "setAsideToDatePence",
          "effectiveRateBps",
          "assumptions",
          "extraInfoTaxYear",
          "extraInfoTaxYearLabel",
          "basedOn",
          "ownerDividendTax"
        ]
      },
      "BooksMoneyInOut": {
        "type": "object",
        "properties": {
          "from": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "to": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "inPence": {
            "type": "integer"
          },
          "outPence": {
            "type": "integer"
          }
        },
        "description": "Money in and out of bank, cash and card accounts; moves between the business’s own accounts are neither.",
        "required": [
          "from",
          "to",
          "inPence",
          "outPence"
        ]
      },
      "BooksHomeProfit": {
        "type": "object",
        "properties": {
          "from": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "to": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "profitPence": {
            "type": "integer"
          },
          "moneyInPence": {
            "type": "integer"
          },
          "costsPence": {
            "type": "integer"
          },
          "compareFrom": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31"
          },
          "compareTo": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31"
          },
          "comparePence": {
            "type": [
              "integer",
              "null"
            ]
          }
        },
        "description": "Profit for the year so far, with the same stretch of last year when the books go back that far.",
        "required": [
          "from",
          "to",
          "profitPence",
          "moneyInPence",
          "costsPence",
          "compareFrom",
          "compareTo",
          "comparePence"
        ]
      },
      "BooksCashAccountKind": {
        "type": "string",
        "enum": [
          "bank",
          "cash",
          "credit_card"
        ]
      },
      "BooksCashAccount": {
        "type": "object",
        "properties": {
          "accountId": {
            "type": "string",
            "format": "uuid"
          },
          "code": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "ownerName": {
            "type": "string"
          },
          "kind": {
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksCashAccountKind"
              }
            ]
          },
          "balancePence": {
            "type": "integer",
            "description": "Debit positive: money held is positive, a card balance owed negative."
          }
        },
        "required": [
          "accountId",
          "code",
          "name",
          "ownerName",
          "kind",
          "balancePence"
        ]
      },
      "BooksHomeCash": {
        "type": "object",
        "properties": {
          "totalPence": {
            "type": "integer"
          },
          "accounts": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BooksCashAccount"
            }
          }
        },
        "required": [
          "totalPence",
          "accounts"
        ]
      },
      "BooksHomeOwed": {
        "type": "object",
        "properties": {
          "totalPence": {
            "type": "integer"
          },
          "overduePence": {
            "type": "integer"
          },
          "contacts": {
            "type": "integer",
            "description": "Customers (or suppliers) with something outstanding."
          },
          "basis": {
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksAgedBasis"
              }
            ]
          }
        },
        "required": [
          "totalPence",
          "overduePence",
          "contacts",
          "basis"
        ]
      },
      "BooksHomeVat": {
        "type": "object",
        "properties": {
          "registered": {
            "type": "boolean"
          },
          "owedPence": {
            "type": "integer",
            "description": "The VAT control account: owed to HMRC is positive."
          }
        },
        "required": [
          "registered",
          "owedPence"
        ]
      },
      "BooksNeedsYouKey": {
        "type": "string",
        "enum": [
          "inbox",
          "receipts",
          "vat",
          "invoices"
        ],
        "description": "invoices appears only when a repeating invoice has made drafts to check."
      },
      "BooksNeedsYou": {
        "type": "object",
        "properties": {
          "key": {
            "description": "invoices appears only when a repeating invoice has made drafts to check.",
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksNeedsYouKey"
              }
            ]
          },
          "label": {
            "type": "string"
          },
          "count": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Null when Tolvi can’t count it yet."
          },
          "detail": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "key",
          "label",
          "count",
          "detail"
        ]
      },
      "BooksMonthSentencePart": {
        "type": "object",
        "properties": {
          "text": {
            "type": "string"
          },
          "linked": {
            "type": "boolean",
            "description": "A figure to link to the profit and loss for the period."
          }
        },
        "required": [
          "text",
          "linked"
        ]
      },
      "BooksMonthSentence": {
        "type": "object",
        "properties": {
          "text": {
            "type": "string"
          },
          "parts": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BooksMonthSentencePart"
            }
          },
          "from": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "to": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "hasFigures": {
            "type": "boolean",
            "description": "False when nothing is in the books for the period."
          }
        },
        "description": "\"This month in a sentence\": worked out from the figures with fixed wording, not written by AI.",
        "required": [
          "text",
          "parts",
          "from",
          "to",
          "hasFigures"
        ]
      },
      "BooksHome": {
        "type": "object",
        "properties": {
          "asAt": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "businessName": {
            "type": "string"
          },
          "yearStart": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "yearEnd": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "thisMonth": {
            "$ref": "#/components/schemas/BooksMoneyInOut"
          },
          "lastMonth": {
            "$ref": "#/components/schemas/BooksMoneyInOut"
          },
          "profit": {
            "$ref": "#/components/schemas/BooksHomeProfit"
          },
          "cash": {
            "$ref": "#/components/schemas/BooksHomeCash"
          },
          "owedToYou": {
            "$ref": "#/components/schemas/BooksHomeOwed"
          },
          "youOwe": {
            "$ref": "#/components/schemas/BooksHomeOwed"
          },
          "vat": {
            "$ref": "#/components/schemas/BooksHomeVat"
          },
          "tax": {
            "description": "Null for partnerships and LLPs (each partner is taxed on their share).",
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksTaxEstimate"
              }
            ]
          },
          "taxUnavailable": {
            "type": [
              "string",
              "null"
            ],
            "description": "Why there is no estimate, in plain words."
          },
          "needsYou": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BooksNeedsYou"
            }
          },
          "monthSentence": {
            "$ref": "#/components/schemas/BooksMonthSentence"
          }
        },
        "description": "The owner’s home screen: money in and out this month, profit so far this year, cash across accounts, who owes the business and whom it owes, VAT owed, the tax to set aside (an estimate) and what needs the owner.",
        "required": [
          "asAt",
          "businessName",
          "yearStart",
          "yearEnd",
          "thisMonth",
          "lastMonth",
          "profit",
          "cash",
          "owedToYou",
          "youOwe",
          "vat",
          "tax",
          "taxUnavailable",
          "needsYou",
          "monthSentence"
        ]
      },
      "BooksTaxDetails": {
        "type": "object",
        "properties": {
          "taxYear": {
            "type": "integer",
            "description": "The tax year’s starting year (2026 = 2026/27)."
          },
          "taxYearLabel": {
            "type": "string",
            "example": "2026/27"
          },
          "employmentIncomePence": {
            "type": "integer",
            "description": "Sole traders. Pay from a job, before tax."
          },
          "employmentTaxPaidPence": {
            "type": "integer",
            "description": "Sole traders. Tax taken from that pay under PAYE."
          },
          "pensionIncomePence": {
            "type": "integer",
            "description": "Sole traders. State and private pensions received, before tax."
          },
          "pensionTaxPaidPence": {
            "type": "integer",
            "description": "Sole traders. Tax taken from pensions under PAYE."
          },
          "propertyIncomePence": {
            "type": "integer",
            "description": "Sole traders. Profit from letting property."
          },
          "savingsInterestPence": {
            "type": "integer",
            "description": "Sole traders. Interest from savings."
          },
          "pensionContributionsPence": {
            "type": "integer",
            "description": "Sole traders. Personal pension contributions paid in."
          },
          "directorSalaryPence": {
            "type": "integer",
            "description": "Companies: the director’s own figure. Planned salary."
          },
          "dividendsPence": {
            "type": "integer",
            "description": "Companies: the director’s own figure. Planned dividends."
          },
          "updatedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "When it was last saved; null when nothing has been entered."
          }
        },
        "description": "Extra information the owner gave for a more accurate tax to set aside, for one tax year. All figures are optional (nil when not entered) and only ever used for the estimate.",
        "required": [
          "taxYear",
          "taxYearLabel",
          "employmentIncomePence",
          "employmentTaxPaidPence",
          "pensionIncomePence",
          "pensionTaxPaidPence",
          "propertyIncomePence",
          "savingsInterestPence",
          "pensionContributionsPence",
          "directorSalaryPence",
          "dividendsPence",
          "updatedAt"
        ]
      },
      "BooksTaxDetailsUpdate": {
        "type": "object",
        "properties": {
          "employmentIncomePence": {
            "type": "integer",
            "minimum": 0,
            "description": "Sole traders. Pay from a job, before tax."
          },
          "employmentTaxPaidPence": {
            "type": "integer",
            "minimum": 0,
            "description": "Sole traders. Tax taken from that pay under PAYE."
          },
          "pensionIncomePence": {
            "type": "integer",
            "minimum": 0,
            "description": "Sole traders. State and private pensions received, before tax."
          },
          "pensionTaxPaidPence": {
            "type": "integer",
            "minimum": 0,
            "description": "Sole traders. Tax taken from pensions under PAYE."
          },
          "propertyIncomePence": {
            "type": "integer",
            "minimum": 0,
            "description": "Sole traders. Profit from letting property."
          },
          "savingsInterestPence": {
            "type": "integer",
            "minimum": 0,
            "description": "Sole traders. Interest from savings."
          },
          "pensionContributionsPence": {
            "type": "integer",
            "minimum": 0,
            "description": "Sole traders. Personal pension contributions paid in (relief at source); Tolvi adds basic rate relief."
          },
          "directorSalaryPence": {
            "type": "integer",
            "minimum": 0,
            "description": "Companies: the director’s own figure. Planned salary for the tax year."
          },
          "dividendsPence": {
            "type": "integer",
            "minimum": 0,
            "description": "Companies: the director’s own figure. Planned dividends for the tax year."
          }
        },
        "description": "Replaces the extra information for the tax year. A figure left out is saved as nil."
      },
      "BooksBankUnavailableReason": {
        "type": "string",
        "enum": [
          "not_configured",
          "sandbox_restricted"
        ],
        "description": "Why available is false: not_configured (the provider’s keys aren’t set), or sandbox_restricted (the provider is in its sandbox and this business isn’t one of the few allowed to try it). Null when available."
      },
      "BooksBankProvider": {
        "type": "string",
        "enum": [
          "truelayer",
          "yapily",
          "fake"
        ]
      },
      "BooksBankEnvironment": {
        "type": "string",
        "enum": [
          "sandbox",
          "live"
        ]
      },
      "BooksBankOption": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "name"
        ]
      },
      "BooksBankProviderInfo": {
        "type": "object",
        "properties": {
          "available": {
            "type": "boolean",
            "description": "Whether this business can connect a bank. Statement files always work."
          },
          "reason": {
            "description": "Why available is false: not_configured (the provider’s keys aren’t set), or sandbox_restricted (the provider is in its sandbox and this business isn’t one of the few allowed to try it). Null when available.",
            "oneOf": [
              {
                "$ref": "#/components/schemas/BooksBankUnavailableReason"
              },
              {
                "type": "null"
              }
            ]
          },
          "message": {
            "type": [
              "string",
              "null"
            ],
            "description": "Why, in plain English, when available is false."
          },
          "provider": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/BooksBankProvider"
              },
              {
                "type": "null"
              }
            ]
          },
          "environment": {
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksBankEnvironment"
              }
            ]
          },
          "banks": {
            "description": "Banks to pick from; empty when the provider shows its own picker.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BooksBankOption"
            }
          },
          "chooseBank": {
            "type": "boolean",
            "description": "The person chooses their bank in Tolvi before connecting (send its id as bankId): Yapily has no picker of its own."
          }
        },
        "required": [
          "available",
          "reason",
          "message",
          "provider",
          "environment",
          "banks",
          "chooseBank"
        ]
      },
      "BooksBankAccountKind": {
        "type": "string",
        "enum": [
          "current",
          "savings",
          "credit_card",
          "other"
        ]
      },
      "BooksBankConnectionStatus": {
        "type": "string",
        "enum": [
          "pending",
          "active",
          "expired",
          "revoked",
          "error"
        ]
      },
      "BooksBankConsentState": {
        "type": "string",
        "enum": [
          "active",
          "reconfirm_soon",
          "reconfirm_required",
          "revoked"
        ],
        "description": "Where the connection stands against the 90 days. reconfirm_soon: in the last 14 days."
      },
      "BooksBankConnection": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "provider": {
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksBankProvider"
              }
            ]
          },
          "status": {
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksBankConnectionStatus"
              }
            ]
          },
          "bankName": {
            "type": [
              "string",
              "null"
            ]
          },
          "consentState": {
            "description": "Where the connection stands against the 90 days. reconfirm_soon: in the last 14 days.",
            "oneOf": [
              {
                "$ref": "#/components/schemas/BooksBankConsentState"
              },
              {
                "type": "null"
              }
            ]
          },
          "consentExpiresAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "daysLeft": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Whole days until access stops; negative once it has."
          },
          "lastSyncedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "lastError": {
            "type": [
              "string",
              "null"
            ],
            "description": "Why the last sync didn’t work, in plain English."
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "description": "One consent at one bank, through the open-banking provider. Access lasts 90 days at a time; the person reconfirms it in Tolvi (FCA SCA-RTS Article 10A).",
        "required": [
          "id",
          "provider",
          "status",
          "bankName",
          "consentState",
          "consentExpiresAt",
          "daysLeft",
          "lastSyncedAt",
          "lastError",
          "createdAt"
        ]
      },
      "BooksBankPendingLine": {
        "type": "object",
        "properties": {
          "date": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "description": {
            "type": "string"
          },
          "amountPence": {
            "type": "integer",
            "description": "Money in positive, money out negative."
          }
        },
        "description": "Not yet booked by the bank: shown, never posted.",
        "required": [
          "date",
          "description",
          "amountPence"
        ]
      },
      "BooksBankAccount": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "kind": {
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksBankAccountKind"
              }
            ]
          },
          "bankName": {
            "type": [
              "string",
              "null"
            ]
          },
          "sortCode": {
            "type": [
              "string",
              "null"
            ]
          },
          "accountNumberEnding": {
            "type": [
              "string",
              "null"
            ],
            "description": "The last four digits only."
          },
          "currency": {
            "type": "string"
          },
          "ledgerAccountId": {
            "type": "string",
            "format": "uuid"
          },
          "ledgerAccountCode": {
            "type": "string"
          },
          "ledgerAccountName": {
            "type": "string"
          },
          "connection": {
            "description": "Null for an account kept up to date with statement files.",
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksBankConnection"
              }
            ]
          },
          "lastSyncedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "bankBalancePence": {
            "type": [
              "integer",
              "null"
            ],
            "description": "The bank’s own balance at the last sync."
          },
          "bankBalanceAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "statementBalancePence": {
            "type": [
              "integer",
              "null"
            ]
          },
          "statementBalanceDate": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31"
          },
          "ledgerBalancePence": {
            "type": "integer",
            "description": "The balance in the books (money in the account positive)."
          },
          "toExplain": {
            "type": "integer",
            "description": "Lines still to explain."
          },
          "pending": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BooksBankPendingLine"
            }
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "description": "A business bank, savings or card account, tied to one account in the books.",
        "required": [
          "id",
          "name",
          "kind",
          "bankName",
          "sortCode",
          "accountNumberEnding",
          "currency",
          "ledgerAccountId",
          "ledgerAccountCode",
          "ledgerAccountName",
          "connection",
          "lastSyncedAt",
          "bankBalancePence",
          "bankBalanceAt",
          "statementBalancePence",
          "statementBalanceDate",
          "ledgerBalancePence",
          "toExplain",
          "pending",
          "createdAt"
        ]
      },
      "BooksBankAccountList": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BooksBankAccount"
            }
          },
          "connections": {
            "description": "Every bank connection, including ones waiting for the person to pick accounts.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BooksBankConnection"
            }
          }
        },
        "required": [
          "items",
          "connections"
        ]
      },
      "BooksBankCreateAccount": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "maxLength": 120
          },
          "kind": {
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksBankAccountKind"
              }
            ]
          },
          "bankName": {
            "type": "string"
          },
          "sortCode": {
            "type": "string",
            "example": "12-34-56"
          },
          "accountNumber": {
            "type": "string"
          },
          "ledgerAccountId": {
            "type": "string",
            "format": "uuid",
            "description": "The ledger account; left out, Tolvi picks a free one or adds one."
          }
        },
        "required": [
          "name"
        ]
      },
      "BooksBankUpdateAccount": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string"
          },
          "statementBalancePence": {
            "type": [
              "integer",
              "null"
            ]
          },
          "statementBalanceDate": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31"
          }
        }
      },
      "BooksBankBalanceSource": {
        "type": "string",
        "enum": [
          "statement",
          "bank_feed",
          "running_balance"
        ]
      },
      "BooksBankReconciliationKind": {
        "type": "string",
        "enum": [
          "to_explain",
          "not_on_statement",
          "unexplained"
        ]
      },
      "BooksBankReconciliationItem": {
        "type": "object",
        "properties": {
          "kind": {
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksBankReconciliationKind"
              }
            ]
          },
          "label": {
            "type": "string"
          },
          "count": {
            "type": "integer"
          },
          "amountPence": {
            "type": "integer"
          }
        },
        "required": [
          "kind",
          "label",
          "count",
          "amountPence"
        ]
      },
      "BooksBankReconciliation": {
        "type": "object",
        "properties": {
          "bankAccountId": {
            "type": "string",
            "format": "uuid"
          },
          "asAt": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "statementBalancePence": {
            "type": [
              "integer",
              "null"
            ]
          },
          "statementSource": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/BooksBankBalanceSource"
              },
              {
                "type": "null"
              }
            ]
          },
          "ledgerBalancePence": {
            "type": "integer"
          },
          "differencePence": {
            "type": [
              "integer",
              "null"
            ]
          },
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BooksBankReconciliationItem"
            }
          },
          "reconciled": {
            "type": "boolean",
            "description": "The difference is fully explained."
          }
        },
        "description": "The statement (or bank) balance against the balance in the books, with the difference explained.",
        "required": [
          "bankAccountId",
          "asAt",
          "statementBalancePence",
          "statementSource",
          "ledgerBalancePence",
          "differencePence",
          "items",
          "reconciled"
        ]
      },
      "BooksBankStatementFile": {
        "type": "object",
        "properties": {
          "fileName": {
            "type": "string"
          },
          "contentBase64": {
            "type": "string",
            "description": "The file, base64 encoded (CSV, OFX, QFX, QIF or Santander’s text download; up to 8 MB)."
          },
          "columns": {
            "type": "object",
            "additionalProperties": true,
            "description": "For an unrecognised CSV: { date, amount | paidIn + paidOut, description: [..], headerRow?, amountSign? } (0-based columns)."
          }
        },
        "required": [
          "fileName",
          "contentBase64"
        ]
      },
      "BooksBankCsvColumns": {
        "type": "object",
        "properties": {
          "headers": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "sample": {
            "type": "array",
            "items": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "description": "The first rows, each an array of cells."
          },
          "suggested": {
            "type": "object",
            "additionalProperties": true,
            "description": "Tolvi’s best guess at the columns (0-based indexes)."
          },
          "headerRow": {
            "type": [
              "integer",
              "null"
            ]
          }
        },
        "description": "For a CSV Tolvi doesn’t recognise: the headings and first rows, for choosing the columns.",
        "required": [
          "headers",
          "sample",
          "suggested",
          "headerRow"
        ]
      },
      "BooksBankStatementIssue": {
        "type": "object",
        "properties": {
          "row": {
            "type": [
              "integer",
              "null"
            ],
            "description": "The 1-based row or record number."
          },
          "message": {
            "type": "string"
          }
        },
        "description": "A row left out of a statement, and why.",
        "required": [
          "row",
          "message"
        ]
      },
      "BooksBankStatementLine": {
        "type": "object",
        "properties": {
          "bookedAt": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "description": {
            "type": "string"
          },
          "amountPence": {
            "type": "integer"
          },
          "alreadyIn": {
            "type": "boolean",
            "description": "Already in the books from an earlier file or the bank feed."
          }
        },
        "required": [
          "bookedAt",
          "description",
          "amountPence",
          "alreadyIn"
        ]
      },
      "BooksBankStatementPreview": {
        "type": "object",
        "properties": {
          "needsColumns": {
            "type": "boolean",
            "description": "True when Tolvi needs the columns chosen (see csv)."
          },
          "csv": {
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksBankCsvColumns"
              }
            ]
          },
          "format": {
            "type": [
              "string",
              "null"
            ],
            "example": "csv"
          },
          "layout": {
            "type": [
              "string",
              "null"
            ],
            "example": "barclays"
          },
          "linesFound": {
            "type": "integer"
          },
          "linesNew": {
            "type": "integer"
          },
          "linesAlreadyIn": {
            "type": "integer"
          },
          "periodFrom": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31"
          },
          "periodTo": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31"
          },
          "closingBalancePence": {
            "type": [
              "integer",
              "null"
            ]
          },
          "issues": {
            "description": "Rows left out.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BooksBankStatementIssue"
            }
          },
          "sample": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BooksBankStatementLine"
            }
          }
        },
        "required": [
          "needsColumns",
          "csv",
          "format",
          "layout",
          "linesFound",
          "linesNew",
          "linesAlreadyIn",
          "periodFrom",
          "periodTo",
          "closingBalancePence",
          "issues",
          "sample"
        ]
      },
      "BooksBankImport": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "bankAccountId": {
            "type": "string",
            "format": "uuid"
          },
          "fileName": {
            "type": "string"
          },
          "format": {
            "type": "string"
          },
          "linesFound": {
            "type": "integer"
          },
          "linesAdded": {
            "type": "integer"
          },
          "linesAlreadyIn": {
            "type": "integer"
          },
          "issues": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BooksBankStatementIssue"
            }
          },
          "periodFrom": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31"
          },
          "periodTo": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "bankAccountId",
          "fileName",
          "format",
          "linesFound",
          "linesAdded",
          "linesAlreadyIn",
          "issues",
          "periodFrom",
          "periodTo",
          "createdAt"
        ]
      },
      "BooksBankStartConnection": {
        "type": "object",
        "properties": {
          "bankId": {
            "type": "string",
            "description": "The provider’s id for the bank the person chose (from providers.banks). Required when providers.chooseBank is true; otherwise it skips the provider’s own picker."
          }
        }
      },
      "BooksBankConnectStart": {
        "type": "object",
        "properties": {
          "connectionId": {
            "type": "string",
            "format": "uuid"
          },
          "url": {
            "type": "string",
            "description": "Send the person’s browser here. The provider handles the bank’s sign-in, then returns to Tolvi with a code."
          }
        },
        "required": [
          "connectionId",
          "url"
        ]
      },
      "BooksBankConnectionCallback": {
        "type": "object",
        "properties": {
          "state": {
            "type": "string"
          },
          "code": {
            "type": "string"
          },
          "error": {
            "type": "string"
          },
          "errorDescription": {
            "type": "string"
          },
          "params": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            },
            "description": "Every query parameter the provider sent back, as is. The provider reads its own (Yapily sends a one-time token, not a code). Up to 30."
          }
        },
        "description": "What the provider sent back on the redirect.",
        "required": [
          "state"
        ]
      },
      "BooksBankProviderAccount": {
        "type": "object",
        "properties": {
          "providerAccountId": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "kind": {
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksBankAccountKind"
              }
            ]
          },
          "sortCode": {
            "type": [
              "string",
              "null"
            ]
          },
          "accountNumberEnding": {
            "type": [
              "string",
              "null"
            ],
            "description": "The last four digits only."
          },
          "currency": {
            "type": "string"
          },
          "bankAccountId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid",
            "description": "Already in Tolvi as this bank account."
          },
          "suggestedLedgerAccountId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid",
            "description": "The ledger account Tolvi suggests; null means Tolvi adds one."
          }
        },
        "description": "An account the bank shared, to choose which to add.",
        "required": [
          "providerAccountId",
          "name",
          "kind",
          "sortCode",
          "accountNumberEnding",
          "currency",
          "bankAccountId",
          "suggestedLedgerAccountId"
        ]
      },
      "BooksBankConnectionAccounts": {
        "type": "object",
        "properties": {
          "connection": {
            "$ref": "#/components/schemas/BooksBankConnection"
          },
          "accounts": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BooksBankProviderAccount"
            }
          }
        },
        "required": [
          "connection",
          "accounts"
        ]
      },
      "BooksBankAddAccount": {
        "type": "object",
        "properties": {
          "providerAccountId": {
            "type": "string"
          },
          "ledgerAccountId": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          }
        },
        "required": [
          "providerAccountId"
        ]
      },
      "BooksBankAddAccounts": {
        "type": "object",
        "properties": {
          "accounts": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BooksBankAddAccount"
            }
          }
        },
        "required": [
          "accounts"
        ]
      },
      "BooksBankReconfirm": {
        "type": "object",
        "properties": {
          "keepSharing": {
            "type": "boolean",
            "description": "Must be true: the person ticked “Keep sharing”."
          }
        },
        "required": [
          "keepSharing"
        ]
      },
      "BooksBankReconfirmResult": {
        "type": "object",
        "properties": {
          "connection": {
            "$ref": "#/components/schemas/BooksBankConnection"
          },
          "url": {
            "type": [
              "string",
              "null"
            ],
            "description": "When the bank wants the person to sign in again: send them here."
          }
        },
        "required": [
          "connection",
          "url"
        ]
      },
      "BooksBankLineSource": {
        "type": "string",
        "enum": [
          "feed",
          "csv",
          "ofx",
          "qif",
          "manual"
        ]
      },
      "BooksBankLineStatus": {
        "type": "string",
        "enum": [
          "to_explain",
          "explained",
          "excluded"
        ],
        "description": "to_explain, explained (in the books), or excluded (set aside)."
      },
      "BooksBankSuggestionLevel": {
        "type": "string",
        "enum": [
          "sorted",
          "suggested",
          "question"
        ]
      },
      "BooksBankSuggestionStage": {
        "type": "string",
        "enum": [
          "duplicate",
          "matched",
          "ruled",
          "remembered",
          "ai",
          "for_ai"
        ],
        "description": "Which step decided: a possible copy, a match, your rule, what you did before, Tolvi AI, or nothing yet (for_ai)."
      },
      "BooksBankSuggestionKind": {
        "type": "string",
        "enum": [
          "category",
          "transfer",
          "match",
          "duplicate",
          "none"
        ]
      },
      "BooksBankSplitPart": {
        "type": "object",
        "properties": {
          "accountCode": {
            "type": "string"
          },
          "vatCode": {
            "type": [
              "string",
              "null"
            ]
          },
          "shareBps": {
            "type": "integer",
            "minimum": 1,
            "maximum": 9999
          }
        },
        "description": "One part of a split: an account, its VAT code and its share in basis points (3000 = 30%).",
        "required": [
          "accountCode",
          "vatCode",
          "shareBps"
        ]
      },
      "BooksBankCategorisation": {
        "type": "object",
        "properties": {
          "accountCode": {
            "type": "string"
          },
          "accountName": {
            "type": [
              "string",
              "null"
            ]
          },
          "vatCode": {
            "type": [
              "string",
              "null"
            ],
            "description": "Null or NONE: no VAT."
          },
          "split": {
            "description": "Empty when not split.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BooksBankSplitPart"
            }
          }
        },
        "description": "A category (account code) and VAT code; a split gives each part’s share in basis points.",
        "required": [
          "accountCode",
          "accountName",
          "vatCode",
          "split"
        ]
      },
      "BooksBankDocumentKind": {
        "type": "string",
        "enum": [
          "receipt",
          "sales_invoice",
          "sales_credit_note",
          "bill",
          "supplier_credit",
          "vat_return",
          "loan_repayment"
        ]
      },
      "BooksBankMatchBand": {
        "type": "string",
        "enum": [
          "high",
          "medium",
          "low"
        ]
      },
      "BooksBankCandidate": {
        "type": "object",
        "properties": {
          "summary": {
            "type": "string"
          },
          "score": {
            "type": "integer",
            "minimum": 0,
            "maximum": 100
          },
          "band": {
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksBankMatchBand"
              }
            ]
          },
          "kind": {
            "type": "string",
            "description": "transfer, or the kind of document."
          },
          "documentIds": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "bankAccountId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "otherLineId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          }
        },
        "description": "Another possible match for a line.",
        "required": [
          "summary",
          "score",
          "band",
          "kind",
          "documentIds",
          "bankAccountId",
          "otherLineId"
        ]
      },
      "BooksBankSuggestion": {
        "type": "object",
        "properties": {
          "level": {
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksBankSuggestionLevel"
              }
            ]
          },
          "stage": {
            "description": "Which step decided: a possible copy, a match, your rule, what you did before, Tolvi AI, or nothing yet (for_ai).",
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksBankSuggestionStage"
              }
            ]
          },
          "summary": {
            "type": "string"
          },
          "reasons": {
            "description": "The “Why?”.",
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "kind": {
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksBankSuggestionKind"
              }
            ]
          },
          "categorisation": {
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksBankCategorisation"
              }
            ]
          },
          "transferBankAccountId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "otherLineId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "documentKind": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/BooksBankDocumentKind"
              },
              {
                "type": "null"
              }
            ]
          },
          "documentIds": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "duplicateOfId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "ruleId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "ruleName": {
            "type": [
              "string",
              "null"
            ]
          },
          "candidates": {
            "description": "Other possible matches, best first.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BooksBankCandidate"
            }
          }
        },
        "description": "What Tolvi suggests for a line and why. Only an owner’s rule set to post automatically ever posts without a tap.",
        "required": [
          "level",
          "stage",
          "summary",
          "reasons",
          "kind",
          "categorisation",
          "transferBankAccountId",
          "otherLineId",
          "documentKind",
          "documentIds",
          "duplicateOfId",
          "ruleId",
          "ruleName",
          "candidates"
        ]
      },
      "BooksBankExplanationKind": {
        "type": "string",
        "enum": [
          "category",
          "transfer",
          "match"
        ]
      },
      "BooksBankExplanation": {
        "type": "object",
        "properties": {
          "kind": {
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksBankExplanationKind"
              }
            ]
          },
          "entryId": {
            "type": "string",
            "format": "uuid"
          },
          "categorisation": {
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksBankCategorisation"
              }
            ]
          },
          "transferLineId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "receiptId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "ruleId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid",
            "description": "The rule that posted it without a tap."
          },
          "ruleVersion": {
            "type": [
              "integer",
              "null"
            ]
          },
          "explainedBy": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "explainedAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "description": "How the line is in the books.",
        "required": [
          "kind",
          "entryId",
          "categorisation",
          "transferLineId",
          "receiptId",
          "ruleId",
          "ruleVersion",
          "explainedBy",
          "explainedAt"
        ]
      },
      "BooksBankLine": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "bankAccountId": {
            "type": "string",
            "format": "uuid"
          },
          "source": {
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksBankLineSource"
              }
            ]
          },
          "bookedAt": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "description": {
            "type": "string"
          },
          "counterparty": {
            "type": [
              "string",
              "null"
            ]
          },
          "reference": {
            "type": [
              "string",
              "null"
            ]
          },
          "payee": {
            "type": [
              "string",
              "null"
            ],
            "description": "Who it was paid to or received from, cleaned up."
          },
          "amountPence": {
            "type": "integer"
          },
          "currency": {
            "type": "string"
          },
          "runningBalancePence": {
            "type": [
              "integer",
              "null"
            ]
          },
          "status": {
            "description": "to_explain, explained (in the books), or excluded (set aside).",
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksBankLineStatus"
              }
            ]
          },
          "suggestion": {
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksBankSuggestion"
              }
            ]
          },
          "explanation": {
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksBankExplanation"
              }
            ]
          },
          "bankChange": {
            "type": [
              "object",
              "null"
            ],
            "additionalProperties": true,
            "description": "The bank changed or withdrew this line after Tolvi read it: { kind: corrected | missing, changed, amountPence, description, bookedAt }."
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "description": "A line from the bank or a statement: what happened, what Tolvi suggests and how it is in the books. Money in positive, money out negative.",
        "required": [
          "id",
          "bankAccountId",
          "source",
          "bookedAt",
          "description",
          "counterparty",
          "reference",
          "payee",
          "amountPence",
          "currency",
          "runningBalancePence",
          "status",
          "suggestion",
          "explanation",
          "bankChange",
          "createdAt"
        ]
      },
      "BooksBankLineCounts": {
        "type": "object",
        "properties": {
          "toExplain": {
            "type": "integer"
          },
          "explained": {
            "type": "integer"
          },
          "excluded": {
            "type": "integer"
          }
        },
        "required": [
          "toExplain",
          "explained",
          "excluded"
        ]
      },
      "BooksBankLineList": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BooksBankLine"
            }
          },
          "counts": {
            "$ref": "#/components/schemas/BooksBankLineCounts"
          },
          "total": {
            "type": "integer",
            "description": "Lines matching the filter (for paging with offset)."
          }
        },
        "required": [
          "items",
          "counts",
          "total"
        ]
      },
      "BooksBankSplitPartInput": {
        "type": "object",
        "properties": {
          "accountCode": {
            "type": "string"
          },
          "vatCode": {
            "type": [
              "string",
              "null"
            ]
          },
          "shareBps": {
            "type": "integer",
            "minimum": 1,
            "maximum": 9999
          }
        },
        "required": [
          "accountCode",
          "shareBps"
        ]
      },
      "BooksBankCategorisationInput": {
        "type": "object",
        "properties": {
          "accountCode": {
            "type": "string"
          },
          "vatCode": {
            "type": [
              "string",
              "null"
            ]
          },
          "split": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BooksBankSplitPartInput"
            }
          }
        },
        "description": "An account code and VAT code (null: no VAT), or a split.",
        "required": [
          "accountCode"
        ]
      },
      "BooksBankConfirmLines": {
        "type": "object",
        "properties": {
          "lineIds": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "categorisation": {
            "description": "The same category for every line; left out, each is confirmed as suggested.",
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksBankCategorisationInput"
              }
            ]
          }
        },
        "required": [
          "lineIds"
        ]
      },
      "BooksBankConfirmResult": {
        "type": "object",
        "properties": {
          "lineId": {
            "type": "string",
            "format": "uuid"
          },
          "ok": {
            "type": "boolean"
          },
          "problem": {
            "type": [
              "string",
              "null"
            ],
            "description": "Why this line wasn’t confirmed."
          }
        },
        "required": [
          "lineId",
          "ok",
          "problem"
        ]
      },
      "BooksBankConfirmResults": {
        "type": "object",
        "properties": {
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BooksBankConfirmResult"
            }
          },
          "confirmed": {
            "type": "integer"
          }
        },
        "required": [
          "results",
          "confirmed"
        ]
      },
      "BooksBankExplainKind": {
        "type": "string",
        "enum": [
          "suggested",
          "category",
          "transfer",
          "match",
          "bill",
          "vat_return"
        ]
      },
      "BooksBankExplainLine": {
        "type": "object",
        "properties": {
          "kind": {
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksBankExplainKind"
              }
            ]
          },
          "billId": {
            "type": "string",
            "format": "uuid"
          },
          "accountCode": {
            "type": "string"
          },
          "vatCode": {
            "type": [
              "string",
              "null"
            ]
          },
          "split": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BooksBankSplitPartInput"
            }
          },
          "toBankAccountId": {
            "type": "string",
            "format": "uuid"
          },
          "otherLineId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "receiptId": {
            "type": "string",
            "format": "uuid"
          },
          "submissionId": {
            "type": "string",
            "format": "uuid",
            "description": "The filed VAT return this payment settles."
          }
        },
        "description": "kind: suggested (confirm the suggestion), category ({ accountCode, vatCode?, split? }), transfer ({ toBankAccountId, otherLineId? }), match ({ receiptId, accountCode? }), bill ({ billId }: money out paying a bill, in full or in part) or vat_return ({ submissionId }: a payment to or from HMRC for a filed return).",
        "required": [
          "kind"
        ]
      },
      "BooksBankRuleMatch": {
        "type": "string",
        "enum": [
          "all",
          "any"
        ]
      },
      "BooksBankRuleField": {
        "type": "string",
        "enum": [
          "description",
          "merchant",
          "counterparty",
          "reference",
          "amount",
          "direction",
          "payment_type",
          "bank_account"
        ]
      },
      "BooksBankRuleCondition": {
        "type": "object",
        "properties": {
          "field": {
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksBankRuleField"
              }
            ]
          },
          "op": {
            "type": "string",
            "example": "contains"
          },
          "value": {
            "type": "string"
          },
          "pence": {
            "type": "integer",
            "minimum": 0
          },
          "toPence": {
            "type": "integer",
            "minimum": 0
          }
        },
        "description": "description, merchant (payee), counterparty or reference with contains, not_contains, starts_with or is and a value; amount with under, over, at_most, at_least, equals or between and pence (toPence for between); direction is in or out; payment_type is a kind; bank_account is an account id.",
        "required": [
          "field",
          "op"
        ]
      },
      "BooksBankRuleAuthor": {
        "type": "string",
        "enum": [
          "owner",
          "accountant"
        ]
      },
      "BooksBankRule": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "version": {
            "type": "integer"
          },
          "name": {
            "type": [
              "string",
              "null"
            ]
          },
          "description": {
            "type": "string",
            "description": "The rule as a sentence."
          },
          "enabled": {
            "type": "boolean"
          },
          "priority": {
            "type": "integer"
          },
          "match": {
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksBankRuleMatch"
              }
            ]
          },
          "conditions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BooksBankRuleCondition"
            }
          },
          "categorise": {
            "$ref": "#/components/schemas/BooksBankCategorisation"
          },
          "postWithoutAsking": {
            "type": "boolean"
          },
          "autoPostLimitPence": {
            "type": [
              "integer",
              "null"
            ]
          },
          "createdBy": {
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksBankRuleAuthor"
              }
            ]
          },
          "applied": {
            "type": "integer",
            "description": "Lines this rule explained (all versions)."
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "description": "An owner’s (or accountant’s) rule, current version. It suggests, or posts without a tap only when the owner chose that.",
        "required": [
          "id",
          "version",
          "name",
          "description",
          "enabled",
          "priority",
          "match",
          "conditions",
          "categorise",
          "postWithoutAsking",
          "autoPostLimitPence",
          "createdBy",
          "applied",
          "updatedAt"
        ]
      },
      "BooksBankRuleInput": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string"
          },
          "priority": {
            "type": "integer"
          },
          "enabled": {
            "type": "boolean"
          },
          "match": {
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksBankRuleMatch"
              }
            ]
          },
          "conditions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BooksBankRuleCondition"
            }
          },
          "categorise": {
            "$ref": "#/components/schemas/BooksBankCategorisationInput"
          },
          "postWithoutAsking": {
            "type": "boolean",
            "description": "Post matching lines without a tap. The business’s owners and admins only, signed in."
          },
          "autoPostLimitPence": {
            "type": [
              "integer",
              "null"
            ]
          }
        },
        "required": [
          "conditions",
          "categorise"
        ]
      },
      "BooksBankRulePreviewLine": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "bookedAt": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "description": {
            "type": "string"
          },
          "payee": {
            "type": [
              "string",
              "null"
            ]
          },
          "amountPence": {
            "type": "integer",
            "description": "Money in positive, money out negative."
          },
          "status": {
            "description": "to_explain, explained (in the books), or excluded (set aside).",
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksBankLineStatus"
              }
            ]
          }
        },
        "description": "A past line a rule would catch.",
        "required": [
          "id",
          "bookedAt",
          "description",
          "payee",
          "amountPence",
          "status"
        ]
      },
      "BooksBankRulePreview": {
        "type": "object",
        "properties": {
          "count": {
            "type": "integer"
          },
          "totalPence": {
            "type": "integer"
          },
          "wouldAutoPost": {
            "type": "integer"
          },
          "differentNow": {
            "type": "integer"
          },
          "sampleLineIds": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "sampleLines": {
            "description": "The sample lines themselves (up to 10, newest first), so a preview can show them.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BooksBankRulePreviewLine"
            }
          },
          "summary": {
            "type": "string",
            "example": "This rule would apply to 14 past lines (£512.40)."
          },
          "problems": {
            "description": "Problems with the rule, if any.",
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        },
        "required": [
          "count",
          "totalPence",
          "wouldAutoPost",
          "differentNow",
          "sampleLineIds",
          "summary",
          "problems"
        ]
      },
      "SalesDebtor": {
        "type": "object",
        "properties": {
          "customerId": {
            "type": "string",
            "format": "uuid"
          },
          "customerName": {
            "type": "string"
          },
          "owedPence": {
            "type": "integer"
          },
          "overduePence": {
            "type": "integer"
          },
          "invoices": {
            "type": "integer"
          },
          "oldestDaysOverdue": {
            "type": "integer",
            "description": "Days the oldest unpaid invoice is past due (0 if none is)."
          }
        },
        "description": "One customer who owes the business money.",
        "required": [
          "customerId",
          "customerName",
          "owedPence",
          "overduePence",
          "invoices",
          "oldestDaysOverdue"
        ]
      },
      "SalesSummary": {
        "type": "object",
        "properties": {
          "asAt": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "owedPence": {
            "type": "integer"
          },
          "overduePence": {
            "type": "integer"
          },
          "unpaidInvoices": {
            "type": "integer"
          },
          "overdueInvoices": {
            "type": "integer"
          },
          "drafts": {
            "type": "integer"
          },
          "remindersToApprove": {
            "type": "integer",
            "description": "Reminders waiting for the owner to approve."
          },
          "debtors": {
            "description": "Most overdue first.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SalesDebtor"
            }
          }
        },
        "description": "Who owes the business money, as at today.",
        "required": [
          "asAt",
          "owedPence",
          "overduePence",
          "unpaidInvoices",
          "overdueInvoices",
          "drafts",
          "remindersToApprove",
          "debtors"
        ]
      },
      "SalesLogoStatus": {
        "type": "string",
        "enum": [
          "none",
          "pending_scan",
          "available",
          "rejected"
        ],
        "description": "available: the logo is on invoices. pending_scan: a new logo is being checked for viruses."
      },
      "VatRounding": {
        "type": "string",
        "enum": [
          "invoice",
          "line"
        ],
        "description": "VAT Notice 700 section 17: invoice (total VAT rounded down, para 17.5) or line (each line to the nearest penny, para 17.6)."
      },
      "SalesSettings": {
        "type": "object",
        "properties": {
          "addressLines": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "postcode": {
            "type": [
              "string",
              "null"
            ]
          },
          "email": {
            "type": [
              "string",
              "null"
            ],
            "description": "Shown on invoices; customers’ replies go here."
          },
          "phone": {
            "type": [
              "string",
              "null"
            ]
          },
          "ownerNames": {
            "type": [
              "string",
              "null"
            ],
            "description": "Sole traders and partnerships trading under a business name: the owner’s or partners’ names (Companies Act 2006 s1202)."
          },
          "bankAccountName": {
            "type": [
              "string",
              "null"
            ]
          },
          "bankSortCode": {
            "type": [
              "string",
              "null"
            ],
            "example": "123456"
          },
          "bankAccountNumber": {
            "type": [
              "string",
              "null"
            ],
            "example": "12345678"
          },
          "brandColour": {
            "type": [
              "string",
              "null"
            ],
            "example": "#1F4E79",
            "description": "The accent colour on the business’s invoices; null for Tolvi’s."
          },
          "logoStatus": {
            "description": "available: the logo is on invoices. pending_scan: a new logo is being checked for viruses.",
            "allOf": [
              {
                "$ref": "#/components/schemas/SalesLogoStatus"
              }
            ]
          },
          "vatRounding": {
            "description": "VAT Notice 700 section 17: invoice (total VAT rounded down, para 17.5) or line (each line to the nearest penny, para 17.6).",
            "allOf": [
              {
                "$ref": "#/components/schemas/VatRounding"
              }
            ]
          },
          "defaultTermsDays": {
            "type": "integer",
            "minimum": 0,
            "maximum": 365
          },
          "footerNote": {
            "type": [
              "string",
              "null"
            ]
          },
          "remindersOn": {
            "type": "boolean",
            "description": "Draft reminders for overdue invoices. The owner still approves each one."
          },
          "invoicePrefix": {
            "type": "string",
            "example": "INV-"
          },
          "creditNotePrefix": {
            "type": "string",
            "example": "CN-"
          },
          "numberingChangeable": {
            "type": "boolean",
            "description": "Whether the numbering can still change (nothing issued yet)."
          }
        },
        "description": "What the business’s invoices say about it and how they look.",
        "required": [
          "addressLines",
          "postcode",
          "email",
          "phone",
          "ownerNames",
          "bankAccountName",
          "bankSortCode",
          "bankAccountNumber",
          "brandColour",
          "logoStatus",
          "vatRounding",
          "defaultTermsDays",
          "footerNote",
          "remindersOn",
          "invoicePrefix",
          "creditNotePrefix",
          "numberingChangeable"
        ]
      },
      "SalesSettingsPatch": {
        "type": "object",
        "properties": {
          "addressLines": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "postcode": {
            "type": [
              "string",
              "null"
            ]
          },
          "email": {
            "type": [
              "string",
              "null"
            ]
          },
          "phone": {
            "type": [
              "string",
              "null"
            ]
          },
          "ownerNames": {
            "type": [
              "string",
              "null"
            ]
          },
          "bankAccountName": {
            "type": [
              "string",
              "null"
            ]
          },
          "bankSortCode": {
            "type": [
              "string",
              "null"
            ]
          },
          "bankAccountNumber": {
            "type": [
              "string",
              "null"
            ]
          },
          "brandColour": {
            "type": [
              "string",
              "null"
            ]
          },
          "vatRounding": {
            "allOf": [
              {
                "$ref": "#/components/schemas/VatRounding"
              }
            ]
          },
          "defaultTermsDays": {
            "type": "integer",
            "minimum": 0,
            "maximum": 365
          },
          "footerNote": {
            "type": [
              "string",
              "null"
            ]
          },
          "remindersOn": {
            "type": "boolean"
          },
          "invoicePrefix": {
            "type": "string"
          },
          "creditNotePrefix": {
            "type": "string"
          }
        }
      },
      "SalesLogoType": {
        "type": "string",
        "enum": [
          "image/png",
          "image/jpeg"
        ]
      },
      "SalesLogoUploadRequest": {
        "type": "object",
        "properties": {
          "contentType": {
            "allOf": [
              {
                "$ref": "#/components/schemas/SalesLogoType"
              }
            ]
          },
          "sizeBytes": {
            "type": "integer",
            "minimum": 1,
            "maximum": 524288
          }
        },
        "required": [
          "contentType",
          "sizeBytes"
        ]
      },
      "SalesLogoUpload": {
        "type": "object",
        "properties": {
          "upload": {
            "$ref": "#/components/schemas/PresignedUpload"
          }
        },
        "required": [
          "upload"
        ]
      },
      "SalesLogoLink": {
        "type": "object",
        "properties": {
          "url": {
            "type": [
              "string",
              "null"
            ],
            "format": "uri",
            "description": "A short-lived link to the logo, or null when there is none."
          },
          "contentType": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "url",
          "contentType"
        ]
      },
      "SalesStatementItem": {
        "type": "object",
        "properties": {
          "documentId": {
            "type": "string",
            "format": "uuid"
          },
          "reference": {
            "type": "string"
          },
          "date": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "dueDate": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31"
          },
          "daysOverdue": {
            "type": "integer"
          },
          "bucket": {
            "type": "string",
            "example": "days_1_30"
          },
          "amountPence": {
            "type": "integer"
          },
          "openPence": {
            "type": "integer"
          }
        },
        "required": [
          "documentId",
          "reference",
          "date",
          "dueDate",
          "daysOverdue",
          "bucket",
          "amountPence",
          "openPence"
        ]
      },
      "SalesStatementAgeing": {
        "type": "object",
        "properties": {
          "current": {
            "type": "integer"
          },
          "days_1_30": {
            "type": "integer"
          },
          "days_31_60": {
            "type": "integer"
          },
          "days_61_90": {
            "type": "integer"
          },
          "over_90": {
            "type": "integer"
          }
        },
        "required": [
          "current",
          "days_1_30",
          "days_31_60",
          "days_61_90",
          "over_90"
        ]
      },
      "SalesStatementEmailDraft": {
        "type": "object",
        "properties": {
          "to": {
            "type": [
              "string",
              "null"
            ]
          },
          "subject": {
            "type": "string"
          },
          "lines": {
            "description": "The paragraphs of the email. A message of the owner’s own goes after the first.",
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "fileName": {
            "type": "string"
          }
        },
        "description": "The email as it would go, for the owner to read and change first.",
        "required": [
          "to",
          "subject",
          "lines",
          "fileName"
        ]
      },
      "SalesStatementSend": {
        "type": "object",
        "properties": {
          "sentTo": {
            "type": "string"
          },
          "asAt": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "totalPence": {
            "type": "integer"
          },
          "sentAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "sentTo",
          "asAt",
          "totalPence",
          "sentAt"
        ]
      },
      "SalesStatement": {
        "type": "object",
        "properties": {
          "customerId": {
            "type": "string",
            "format": "uuid"
          },
          "customerName": {
            "type": "string"
          },
          "asAt": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SalesStatementItem"
            }
          },
          "ageing": {
            "$ref": "#/components/schemas/SalesStatementAgeing"
          },
          "totalPence": {
            "type": "integer"
          },
          "emailDraft": {
            "$ref": "#/components/schemas/SalesStatementEmailDraft"
          },
          "lastSent": {
            "description": "The last time a statement was emailed to them.",
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/SalesStatementSend"
              }
            ]
          }
        },
        "description": "What a customer owes at a date, invoice by invoice, with ageing.",
        "required": [
          "customerId",
          "customerName",
          "asAt",
          "items",
          "ageing",
          "totalPence",
          "emailDraft",
          "lastSent"
        ]
      },
      "SalesStatementSendInput": {
        "type": "object",
        "properties": {
          "to": {
            "type": "string",
            "description": "Defaults to the customer’s email."
          },
          "subject": {
            "type": "string",
            "maxLength": 200
          },
          "message": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 2000,
            "description": "A short note added to the standard wording."
          },
          "asAt": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31",
            "description": "Defaults to today."
          }
        }
      },
      "Customer": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "email": {
            "type": [
              "string",
              "null"
            ]
          },
          "addressLines": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "postcode": {
            "type": [
              "string",
              "null"
            ]
          },
          "country": {
            "type": "string",
            "example": "GB"
          },
          "vatNumber": {
            "type": [
              "string",
              "null"
            ],
            "example": "GB123456789",
            "description": "Checked for format and check digits; only HMRC can confirm it is registered."
          },
          "isBusiness": {
            "type": "boolean"
          },
          "paymentTermsDays": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Days to pay; null means the business’s usual terms."
          },
          "cisRegistered": {
            "type": "boolean"
          },
          "endUserOrIntermediary": {
            "type": "boolean"
          },
          "remindersPaused": {
            "type": "boolean"
          },
          "archived": {
            "type": "boolean"
          },
          "owedPence": {
            "type": "integer",
            "description": "Still owed on issued invoices, in pence."
          },
          "overduePence": {
            "type": "integer",
            "description": "Of that, past its due date."
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "description": "Someone the business invoices.",
        "required": [
          "id",
          "name",
          "email",
          "addressLines",
          "postcode",
          "country",
          "vatNumber",
          "isBusiness",
          "paymentTermsDays",
          "cisRegistered",
          "endUserOrIntermediary",
          "remindersPaused",
          "archived",
          "owedPence",
          "overduePence",
          "createdAt"
        ]
      },
      "CustomerList": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Customer"
            }
          }
        },
        "required": [
          "items"
        ]
      },
      "CustomerInput": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "maxLength": 200
          },
          "email": {
            "type": [
              "string",
              "null"
            ]
          },
          "addressLines": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "postcode": {
            "type": [
              "string",
              "null"
            ]
          },
          "country": {
            "type": "string",
            "example": "GB"
          },
          "vatNumber": {
            "type": [
              "string",
              "null"
            ]
          },
          "isBusiness": {
            "type": "boolean"
          },
          "paymentTermsDays": {
            "type": [
              "integer",
              "null"
            ]
          },
          "cisRegistered": {
            "type": "boolean"
          },
          "endUserOrIntermediary": {
            "type": "boolean"
          },
          "remindersPaused": {
            "type": "boolean"
          }
        },
        "required": [
          "name"
        ]
      },
      "CustomerPatch": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "maxLength": 200
          },
          "email": {
            "type": [
              "string",
              "null"
            ]
          },
          "addressLines": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "postcode": {
            "type": [
              "string",
              "null"
            ]
          },
          "country": {
            "type": "string"
          },
          "vatNumber": {
            "type": [
              "string",
              "null"
            ]
          },
          "isBusiness": {
            "type": "boolean"
          },
          "paymentTermsDays": {
            "type": [
              "integer",
              "null"
            ]
          },
          "cisRegistered": {
            "type": "boolean"
          },
          "endUserOrIntermediary": {
            "type": "boolean"
          },
          "remindersPaused": {
            "type": "boolean"
          }
        }
      },
      "SalesDocumentKind": {
        "type": "string",
        "enum": [
          "invoice",
          "credit_note"
        ]
      },
      "SalesDocumentState": {
        "type": "string",
        "enum": [
          "draft",
          "issued"
        ],
        "description": "draft: can be changed or deleted. issued: numbered, in the books and never changed."
      },
      "InvoiceStatus": {
        "type": "string",
        "enum": [
          "draft",
          "sent",
          "part_paid",
          "paid",
          "overdue",
          "void"
        ],
        "description": "draft, sent (issued, nothing paid yet), part_paid, paid, overdue, or void (credited in full)."
      },
      "SalesDiscountKind": {
        "type": "string",
        "enum": [
          "percent",
          "amount"
        ]
      },
      "SalesLineDiscount": {
        "type": "object",
        "properties": {
          "kind": {
            "allOf": [
              {
                "$ref": "#/components/schemas/SalesDiscountKind"
              }
            ]
          },
          "bps": {
            "type": "integer",
            "description": "percent: basis points (1000 = 10%)."
          },
          "pence": {
            "type": "integer",
            "description": "amount: pence off the line."
          }
        },
        "required": [
          "kind"
        ]
      },
      "SalesLine": {
        "type": "object",
        "properties": {
          "description": {
            "type": "string",
            "maxLength": 300
          },
          "quantity": {
            "type": "string",
            "example": "3",
            "description": "Up to 3 decimal places. Default 1."
          },
          "unitPricePence": {
            "type": "integer",
            "minimum": 0,
            "description": "Price per unit before VAT, in pence."
          },
          "vatCode": {
            "allOf": [
              {
                "$ref": "#/components/schemas/VatCode"
              }
            ]
          },
          "accountId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid",
            "description": "The income account; the business’s sales account when left out."
          },
          "discount": {
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/SalesLineDiscount"
              }
            ]
          },
          "unitCode": {
            "type": [
              "string",
              "null"
            ],
            "example": "DAY",
            "description": "UN/ECE Recommendation 20 unit code."
          },
          "cisLabour": {
            "type": "boolean",
            "description": "CIS: labour (the deduction is worked on labour only)."
          },
          "netPence": {
            "type": "integer",
            "description": "After any discount, before VAT."
          },
          "vatPence": {
            "type": "integer",
            "description": "VAT charged on the line (its share of the rounded total under invoice rounding)."
          },
          "rateBps": {
            "type": "integer",
            "description": "Basis points (2000 = 20%)."
          }
        },
        "description": "A line with its worked amounts.",
        "required": [
          "description",
          "unitPricePence",
          "vatCode",
          "netPence",
          "vatPence",
          "rateBps"
        ]
      },
      "SalesVatTotal": {
        "type": "object",
        "properties": {
          "code": {
            "allOf": [
              {
                "$ref": "#/components/schemas/VatCode"
              }
            ]
          },
          "rateBps": {
            "type": "integer"
          },
          "netPence": {
            "type": "integer"
          },
          "vatPence": {
            "type": "integer"
          },
          "notionalVatPence": {
            "type": "integer",
            "description": "Reverse charge: the VAT the customer accounts for, shown but not charged."
          }
        },
        "description": "Totals for one VAT code, so zero-rated and exempt supplies are shown apart (VAT Notice 700 para 16.5).",
        "required": [
          "code",
          "rateBps",
          "netPence",
          "vatPence",
          "notionalVatPence"
        ]
      },
      "SalesTotals": {
        "type": "object",
        "properties": {
          "netPence": {
            "type": "integer"
          },
          "vatPence": {
            "type": "integer"
          },
          "grossPence": {
            "type": "integer"
          },
          "amountDuePence": {
            "type": "integer",
            "description": "What the customer pays: the gross less any CIS deduction."
          },
          "notionalVatPence": {
            "type": "integer"
          },
          "cisDeductionPence": {
            "type": "integer"
          },
          "byVatCode": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SalesVatTotal"
            }
          }
        },
        "required": [
          "netPence",
          "vatPence",
          "grossPence",
          "amountDuePence",
          "notionalVatPence",
          "cisDeductionPence",
          "byVatCode"
        ]
      },
      "SalesDocument": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "kind": {
            "allOf": [
              {
                "$ref": "#/components/schemas/SalesDocumentKind"
              }
            ]
          },
          "state": {
            "description": "draft: can be changed or deleted. issued: numbered, in the books and never changed.",
            "allOf": [
              {
                "$ref": "#/components/schemas/SalesDocumentState"
              }
            ]
          },
          "status": {
            "description": "draft, sent (issued, nothing paid yet), part_paid, paid, overdue, or void (credited in full).",
            "allOf": [
              {
                "$ref": "#/components/schemas/InvoiceStatus"
              }
            ]
          },
          "number": {
            "type": [
              "string",
              "null"
            ],
            "example": "INV-0001"
          },
          "opening": {
            "type": "boolean",
            "description": "Issued before the books started and brought forward in the opening balances: it has its old number and no Tolvi copy to print or send."
          },
          "customerId": {
            "type": "string",
            "format": "uuid"
          },
          "customerName": {
            "type": "string"
          },
          "customerEmail": {
            "type": [
              "string",
              "null"
            ]
          },
          "issueDate": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31"
          },
          "supplyDate": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31"
          },
          "taxPoint": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31",
            "description": "The VAT tax point (VATA 1994 s6)."
          },
          "dueDate": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31"
          },
          "termsDays": {
            "type": [
              "integer",
              "null"
            ]
          },
          "rounding": {
            "allOf": [
              {
                "$ref": "#/components/schemas/VatRounding"
              }
            ]
          },
          "reference": {
            "type": [
              "string",
              "null"
            ]
          },
          "purchaseOrder": {
            "type": [
              "string",
              "null"
            ]
          },
          "notes": {
            "type": [
              "string",
              "null"
            ]
          },
          "creditsId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid",
            "description": "Credit notes: the invoice credited."
          },
          "creditsNumber": {
            "type": [
              "string",
              "null"
            ]
          },
          "reason": {
            "type": [
              "string",
              "null"
            ],
            "description": "Credit notes: why."
          },
          "lines": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SalesLine"
            }
          },
          "totals": {
            "$ref": "#/components/schemas/SalesTotals"
          },
          "paidPence": {
            "type": "integer"
          },
          "creditedPence": {
            "type": "integer"
          },
          "outstandingPence": {
            "type": "integer",
            "description": "Still owed (invoices); nil for drafts and credit notes."
          },
          "daysOverdue": {
            "type": "integer"
          },
          "sentAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "sentTo": {
            "type": [
              "string",
              "null"
            ]
          },
          "ledgerEntryId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid",
            "description": "The ledger entry it posted."
          },
          "aiSuggestionId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid",
            "description": "Drafted from a sentence by Tolvi AI."
          },
          "issuedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "description": "An invoice or a credit note. Status and what is owed are worked out from payments and credit notes, never stored.",
        "required": [
          "id",
          "kind",
          "state",
          "status",
          "number",
          "opening",
          "customerId",
          "customerName",
          "customerEmail",
          "issueDate",
          "supplyDate",
          "taxPoint",
          "dueDate",
          "termsDays",
          "rounding",
          "reference",
          "purchaseOrder",
          "notes",
          "creditsId",
          "creditsNumber",
          "reason",
          "lines",
          "totals",
          "paidPence",
          "creditedPence",
          "outstandingPence",
          "daysOverdue",
          "sentAt",
          "sentTo",
          "ledgerEntryId",
          "aiSuggestionId",
          "issuedAt",
          "createdAt",
          "updatedAt"
        ]
      },
      "SalesDocumentList": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SalesDocument"
            }
          }
        },
        "required": [
          "items"
        ]
      },
      "SalesLineInput": {
        "type": "object",
        "properties": {
          "description": {
            "type": "string",
            "maxLength": 300
          },
          "quantity": {
            "type": "string",
            "example": "3",
            "description": "Up to 3 decimal places. Default 1."
          },
          "unitPricePence": {
            "type": "integer",
            "minimum": 0,
            "description": "Price per unit before VAT, in pence."
          },
          "vatCode": {
            "allOf": [
              {
                "$ref": "#/components/schemas/VatCode"
              }
            ]
          },
          "accountId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid",
            "description": "The income account; the business’s sales account when left out."
          },
          "discount": {
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/SalesLineDiscount"
              }
            ]
          },
          "unitCode": {
            "type": [
              "string",
              "null"
            ],
            "example": "DAY",
            "description": "UN/ECE Recommendation 20 unit code."
          },
          "cisLabour": {
            "type": "boolean",
            "description": "CIS: labour (the deduction is worked on labour only)."
          }
        },
        "description": "One line of an invoice or credit note, before VAT is worked out.",
        "required": [
          "description",
          "unitPricePence",
          "vatCode"
        ]
      },
      "CreateSalesDocument": {
        "type": "object",
        "properties": {
          "customerId": {
            "type": "string",
            "format": "uuid"
          },
          "issueDate": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31"
          },
          "supplyDate": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31"
          },
          "dueDate": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31"
          },
          "termsDays": {
            "type": [
              "integer",
              "null"
            ]
          },
          "lines": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SalesLineInput"
            }
          },
          "reference": {
            "type": [
              "string",
              "null"
            ]
          },
          "purchaseOrder": {
            "type": [
              "string",
              "null"
            ]
          },
          "notes": {
            "type": [
              "string",
              "null"
            ]
          },
          "aiSuggestionId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid",
            "description": "The Tolvi AI suggestion it was drafted from."
          }
        },
        "required": [
          "customerId"
        ]
      },
      "SalesParty": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string"
          },
          "addressLines": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "postcode": {
            "type": [
              "string",
              "null"
            ]
          },
          "vatNumber": {
            "type": [
              "string",
              "null"
            ]
          },
          "email": {
            "type": [
              "string",
              "null"
            ]
          },
          "registeredName": {
            "type": [
              "string",
              "null"
            ],
            "description": "Companies and LLPs: the registered name."
          },
          "companyNumber": {
            "type": [
              "string",
              "null"
            ]
          },
          "payTo": {
            "type": [
              "string",
              "null"
            ],
            "description": "How to pay, as printed (the business only)."
          }
        },
        "description": "A business or customer as the document shows it (frozen at issue).",
        "required": [
          "name",
          "addressLines",
          "postcode",
          "vatNumber",
          "email",
          "registeredName",
          "companyNumber",
          "payTo"
        ]
      },
      "SalesProblemSeverity": {
        "type": "string",
        "enum": [
          "error",
          "warning"
        ]
      },
      "SalesProblem": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string",
            "example": "customer_address_missing"
          },
          "severity": {
            "allOf": [
              {
                "$ref": "#/components/schemas/SalesProblemSeverity"
              }
            ]
          },
          "field": {
            "type": [
              "string",
              "null"
            ],
            "example": "customer.address"
          },
          "message": {
            "type": "string"
          },
          "citation": {
            "type": [
              "string",
              "null"
            ],
            "description": "The legislation or HMRC guidance."
          }
        },
        "description": "Something the invoice must fix (error) or should check (warning) before it is issued, with the rule behind it.",
        "required": [
          "code",
          "severity",
          "field",
          "message",
          "citation"
        ]
      },
      "SalesPaymentMethod": {
        "type": "string",
        "enum": [
          "bank_transfer",
          "card",
          "cash",
          "cheque",
          "other"
        ]
      },
      "SalesPayment": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "paidOn": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "amountPence": {
            "type": "integer"
          },
          "method": {
            "allOf": [
              {
                "$ref": "#/components/schemas/SalesPaymentMethod"
              }
            ]
          },
          "accountId": {
            "type": "string",
            "format": "uuid"
          },
          "reference": {
            "type": [
              "string",
              "null"
            ]
          },
          "bankLineId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid",
            "description": "Set when it came from a matched bank line."
          },
          "ledgerEntryId": {
            "type": "string",
            "format": "uuid"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "description": "Money received against an invoice.",
        "required": [
          "id",
          "paidOn",
          "amountPence",
          "method",
          "accountId",
          "reference",
          "bankLineId",
          "ledgerEntryId",
          "createdAt"
        ]
      },
      "SalesCreditApplied": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "number": {
            "type": [
              "string",
              "null"
            ]
          },
          "state": {
            "allOf": [
              {
                "$ref": "#/components/schemas/SalesDocumentState"
              }
            ]
          },
          "issueDate": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31"
          },
          "amountPence": {
            "type": "integer",
            "description": "What it takes off the invoice."
          },
          "reason": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "id",
          "number",
          "state",
          "issueDate",
          "amountPence",
          "reason"
        ]
      },
      "SalesSendKind": {
        "type": "string",
        "enum": [
          "invoice",
          "credit_note",
          "reminder"
        ]
      },
      "SalesSend": {
        "type": "object",
        "properties": {
          "kind": {
            "allOf": [
              {
                "$ref": "#/components/schemas/SalesSendKind"
              }
            ]
          },
          "sentTo": {
            "type": "string"
          },
          "subject": {
            "type": "string"
          },
          "sentAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "description": "An email sent to the customer.",
        "required": [
          "kind",
          "sentTo",
          "subject",
          "sentAt"
        ]
      },
      "ReminderTone": {
        "type": "string",
        "enum": [
          "friendly",
          "firm",
          "final"
        ]
      },
      "ReminderStatus": {
        "type": "string",
        "enum": [
          "to_approve",
          "sent",
          "dismissed"
        ]
      },
      "SalesReminder": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "invoiceId": {
            "type": "string",
            "format": "uuid"
          },
          "invoiceNumber": {
            "type": "string"
          },
          "customerName": {
            "type": "string"
          },
          "customerEmail": {
            "type": [
              "string",
              "null"
            ]
          },
          "tone": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ReminderTone"
              }
            ]
          },
          "daysOverdue": {
            "type": "integer",
            "description": "Negative before the due date."
          },
          "outstandingPence": {
            "type": "integer"
          },
          "compensationPence": {
            "type": "integer",
            "description": "Fixed late payment compensation the owner may add (Late Payment of Commercial Debts (Interest) Act 1998 s5A); not added unless they choose to."
          },
          "subject": {
            "type": "string"
          },
          "body": {
            "type": "string"
          },
          "status": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ReminderStatus"
              }
            ]
          },
          "draftedOn": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "sentAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "sentTo": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "description": "A reminder drafted for an overdue (or nearly due) invoice. It goes only when a person at the business presses Send.",
        "required": [
          "id",
          "invoiceId",
          "invoiceNumber",
          "customerName",
          "customerEmail",
          "tone",
          "daysOverdue",
          "outstandingPence",
          "compensationPence",
          "subject",
          "body",
          "status",
          "draftedOn",
          "sentAt",
          "sentTo"
        ]
      },
      "SalesDocumentDetail": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "kind": {
            "allOf": [
              {
                "$ref": "#/components/schemas/SalesDocumentKind"
              }
            ]
          },
          "state": {
            "description": "draft: can be changed or deleted. issued: numbered, in the books and never changed.",
            "allOf": [
              {
                "$ref": "#/components/schemas/SalesDocumentState"
              }
            ]
          },
          "status": {
            "description": "draft, sent (issued, nothing paid yet), part_paid, paid, overdue, or void (credited in full).",
            "allOf": [
              {
                "$ref": "#/components/schemas/InvoiceStatus"
              }
            ]
          },
          "number": {
            "type": [
              "string",
              "null"
            ],
            "example": "INV-0001"
          },
          "opening": {
            "type": "boolean",
            "description": "Issued before the books started and brought forward in the opening balances: it has its old number and no Tolvi copy to print or send."
          },
          "customerId": {
            "type": "string",
            "format": "uuid"
          },
          "customerName": {
            "type": "string"
          },
          "customerEmail": {
            "type": [
              "string",
              "null"
            ]
          },
          "issueDate": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31"
          },
          "supplyDate": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31"
          },
          "taxPoint": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31",
            "description": "The VAT tax point (VATA 1994 s6)."
          },
          "dueDate": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31"
          },
          "termsDays": {
            "type": [
              "integer",
              "null"
            ]
          },
          "rounding": {
            "allOf": [
              {
                "$ref": "#/components/schemas/VatRounding"
              }
            ]
          },
          "reference": {
            "type": [
              "string",
              "null"
            ]
          },
          "purchaseOrder": {
            "type": [
              "string",
              "null"
            ]
          },
          "notes": {
            "type": [
              "string",
              "null"
            ]
          },
          "creditsId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid",
            "description": "Credit notes: the invoice credited."
          },
          "creditsNumber": {
            "type": [
              "string",
              "null"
            ]
          },
          "reason": {
            "type": [
              "string",
              "null"
            ],
            "description": "Credit notes: why."
          },
          "lines": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SalesLine"
            }
          },
          "totals": {
            "$ref": "#/components/schemas/SalesTotals"
          },
          "paidPence": {
            "type": "integer"
          },
          "creditedPence": {
            "type": "integer"
          },
          "outstandingPence": {
            "type": "integer",
            "description": "Still owed (invoices); nil for drafts and credit notes."
          },
          "daysOverdue": {
            "type": "integer"
          },
          "sentAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "sentTo": {
            "type": [
              "string",
              "null"
            ]
          },
          "ledgerEntryId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid",
            "description": "The ledger entry it posted."
          },
          "aiSuggestionId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid",
            "description": "Drafted from a sentence by Tolvi AI."
          },
          "issuedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          },
          "supplier": {
            "$ref": "#/components/schemas/SalesParty"
          },
          "customer": {
            "$ref": "#/components/schemas/SalesParty"
          },
          "problems": {
            "description": "Drafts: what stops it being issued (errors) and what to check (warnings).",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SalesProblem"
            }
          },
          "payments": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SalesPayment"
            }
          },
          "creditNotes": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SalesCreditApplied"
            }
          },
          "sends": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SalesSend"
            }
          },
          "reminders": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SalesReminder"
            }
          }
        },
        "required": [
          "id",
          "kind",
          "state",
          "status",
          "number",
          "opening",
          "customerId",
          "customerName",
          "customerEmail",
          "issueDate",
          "supplyDate",
          "taxPoint",
          "dueDate",
          "termsDays",
          "rounding",
          "reference",
          "purchaseOrder",
          "notes",
          "creditsId",
          "creditsNumber",
          "reason",
          "lines",
          "totals",
          "paidPence",
          "creditedPence",
          "outstandingPence",
          "daysOverdue",
          "sentAt",
          "sentTo",
          "ledgerEntryId",
          "aiSuggestionId",
          "issuedAt",
          "createdAt",
          "updatedAt",
          "supplier",
          "customer",
          "problems",
          "payments",
          "creditNotes",
          "sends",
          "reminders"
        ]
      },
      "DraftInvoiceFromSentence": {
        "type": "object",
        "properties": {
          "sentence": {
            "type": "string",
            "maxLength": 1000,
            "example": "Invoice Acme for 3 days' consulting at £450 plus VAT"
          }
        },
        "required": [
          "sentence"
        ]
      },
      "SalesCustomerMatch": {
        "type": "string",
        "enum": [
          "existing",
          "new",
          "ambiguous",
          "missing"
        ]
      },
      "SalesDraftQuestion": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string",
            "example": "customer_ambiguous"
          },
          "field": {
            "type": "string"
          },
          "message": {
            "type": "string"
          },
          "blocking": {
            "type": "boolean",
            "description": "Must be answered before the invoice can be issued."
          },
          "options": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "label": {
                  "type": "string"
                }
              },
              "required": [
                "id",
                "label"
              ]
            }
          }
        },
        "description": "Something Tolvi needs the owner to answer or check.",
        "required": [
          "code",
          "field",
          "message",
          "blocking",
          "options"
        ]
      },
      "SalesDraftAssumption": {
        "type": "object",
        "properties": {
          "field": {
            "type": "string"
          },
          "message": {
            "type": "string"
          }
        },
        "required": [
          "field",
          "message"
        ]
      },
      "SalesDraftSuggestion": {
        "type": "object",
        "properties": {
          "suggestionId": {
            "type": "string",
            "format": "uuid",
            "description": "The Tolvi AI suggestion; pass it as aiSuggestionId when saving the draft."
          },
          "customerMatch": {
            "allOf": [
              {
                "$ref": "#/components/schemas/SalesCustomerMatch"
              }
            ]
          },
          "customerId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "customerName": {
            "type": [
              "string",
              "null"
            ]
          },
          "customerEmail": {
            "type": [
              "string",
              "null"
            ]
          },
          "lines": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SalesLine"
            }
          },
          "issueDate": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "supplyDate": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31"
          },
          "dueDate": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31"
          },
          "termsDays": {
            "type": [
              "integer",
              "null"
            ]
          },
          "purchaseOrder": {
            "type": [
              "string",
              "null"
            ]
          },
          "totals": {
            "$ref": "#/components/schemas/SalesTotals"
          },
          "questions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SalesDraftQuestion"
            }
          },
          "assumptions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SalesDraftAssumption"
            }
          },
          "note": {
            "type": "string",
            "description": "Tolvi AI’s note on anything unclear, or \"\"."
          }
        },
        "description": "What Tolvi AI made of the sentence: a suggestion to check and save as a draft. Nothing is saved, issued or sent.",
        "required": [
          "suggestionId",
          "customerMatch",
          "customerId",
          "customerName",
          "customerEmail",
          "lines",
          "issueDate",
          "supplyDate",
          "dueDate",
          "termsDays",
          "purchaseOrder",
          "totals",
          "questions",
          "assumptions",
          "note"
        ]
      },
      "UpdateSalesDocument": {
        "type": "object",
        "properties": {
          "customerId": {
            "type": "string",
            "format": "uuid"
          },
          "issueDate": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31"
          },
          "supplyDate": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31"
          },
          "dueDate": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31"
          },
          "termsDays": {
            "type": [
              "integer",
              "null"
            ]
          },
          "lines": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SalesLineInput"
            }
          },
          "reference": {
            "type": [
              "string",
              "null"
            ]
          },
          "purchaseOrder": {
            "type": [
              "string",
              "null"
            ]
          },
          "notes": {
            "type": [
              "string",
              "null"
            ]
          },
          "reason": {
            "type": [
              "string",
              "null"
            ],
            "description": "Credit notes: why."
          }
        },
        "description": "Change a draft. Fields left out keep their value."
      },
      "IssueSalesDocument": {
        "type": "object",
        "properties": {
          "issueDate": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31",
            "description": "Defaults to the draft’s date, or today."
          }
        }
      },
      "CreditNoteRequest": {
        "type": "object",
        "properties": {
          "reason": {
            "type": "string",
            "maxLength": 300
          },
          "lines": {
            "description": "Leave out to credit the whole invoice.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SalesLineInput"
            }
          },
          "issueDate": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          }
        },
        "required": [
          "reason"
        ]
      },
      "VoidInvoiceRequest": {
        "type": "object",
        "properties": {
          "reason": {
            "type": "string",
            "maxLength": 300
          },
          "issueDate": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          }
        },
        "required": [
          "reason"
        ]
      },
      "RecordSalesPayment": {
        "type": "object",
        "properties": {
          "paidOn": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "amountPence": {
            "type": "integer",
            "minimum": 1
          },
          "method": {
            "allOf": [
              {
                "$ref": "#/components/schemas/SalesPaymentMethod"
              }
            ]
          },
          "accountId": {
            "type": "string",
            "format": "uuid",
            "description": "The bank or cash account the money went into."
          },
          "reference": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "paidOn",
          "amountPence",
          "accountId"
        ]
      },
      "SendSalesDocument": {
        "type": "object",
        "properties": {
          "to": {
            "type": "string",
            "description": "Defaults to the customer’s email."
          },
          "subject": {
            "type": "string",
            "maxLength": 200,
            "description": "The email’s subject. Defaults to \"Invoice INV-0001 from <business>\" (or \"Credit note …\")."
          },
          "message": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 2000
          }
        }
      },
      "SalesReminderList": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SalesReminder"
            }
          }
        },
        "required": [
          "items"
        ]
      },
      "UpdateSalesReminder": {
        "type": "object",
        "properties": {
          "subject": {
            "type": "string",
            "maxLength": 200
          },
          "body": {
            "type": "string",
            "maxLength": 5000
          }
        },
        "required": [
          "subject",
          "body"
        ]
      },
      "SalesRepeatFrequency": {
        "type": "string",
        "enum": [
          "weekly",
          "monthly",
          "quarterly",
          "yearly"
        ]
      },
      "SalesRepeatStatus": {
        "type": "string",
        "enum": [
          "active",
          "paused",
          "stopped"
        ],
        "description": "active: makes one on nextOn. paused: makes none until resumed. stopped: for good."
      },
      "SalesRecurringInvoice": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "customerId": {
            "type": "string",
            "format": "uuid"
          },
          "customerName": {
            "type": "string"
          },
          "customerEmail": {
            "type": [
              "string",
              "null"
            ]
          },
          "sourceDocumentId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid",
            "description": "The invoice it was set up from."
          },
          "frequency": {
            "allOf": [
              {
                "$ref": "#/components/schemas/SalesRepeatFrequency"
              }
            ]
          },
          "frequencyText": {
            "type": "string",
            "example": "every month"
          },
          "status": {
            "description": "active: makes one on nextOn. paused: makes none until resumed. stopped: for good.",
            "allOf": [
              {
                "$ref": "#/components/schemas/SalesRepeatStatus"
              }
            ]
          },
          "nextOn": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31",
            "description": "The next date one is made. Null when paused or stopped."
          },
          "firstOn": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "autoSend": {
            "type": "boolean",
            "description": "false (the default): each one is a draft for the owner to check. true: issued and emailed on the day, in the name of the person who turned it on."
          },
          "autoSendAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "amountPence": {
            "type": "integer",
            "description": "What each one bills, with VAT, in pence."
          },
          "summary": {
            "type": "string",
            "description": "The first line’s description, to recognise it by."
          },
          "lineCount": {
            "type": "integer"
          },
          "runCount": {
            "type": "integer"
          },
          "lastRunOn": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31"
          },
          "lastDocumentId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid",
            "description": "The last invoice made."
          },
          "lastProblem": {
            "type": [
              "string",
              "null"
            ],
            "description": "What went wrong on the last run, in plain words."
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "description": "A repeating invoice: what it bills, how often, and when the next one is made.",
        "required": [
          "id",
          "customerId",
          "customerName",
          "customerEmail",
          "sourceDocumentId",
          "frequency",
          "frequencyText",
          "status",
          "nextOn",
          "firstOn",
          "autoSend",
          "autoSendAt",
          "amountPence",
          "summary",
          "lineCount",
          "runCount",
          "lastRunOn",
          "lastDocumentId",
          "lastProblem",
          "createdAt"
        ]
      },
      "SalesRecurringInvoiceList": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SalesRecurringInvoice"
            }
          }
        },
        "required": [
          "items"
        ]
      },
      "SalesRecurringInvoiceInput": {
        "type": "object",
        "properties": {
          "invoiceId": {
            "type": "string",
            "format": "uuid",
            "description": "The invoice to repeat: its customer, lines, note and terms are copied."
          },
          "frequency": {
            "allOf": [
              {
                "$ref": "#/components/schemas/SalesRepeatFrequency"
              }
            ]
          },
          "firstOn": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31",
            "description": "The first date to make one. Today or later."
          }
        },
        "required": [
          "invoiceId",
          "frequency",
          "firstOn"
        ]
      },
      "SalesRecurringInvoicePatch": {
        "type": "object",
        "properties": {
          "frequency": {
            "allOf": [
              {
                "$ref": "#/components/schemas/SalesRepeatFrequency"
              }
            ]
          },
          "nextOn": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31",
            "description": "The next date to make one. Today or later; later dates follow from it."
          },
          "fromInvoiceId": {
            "type": "string",
            "format": "uuid",
            "description": "Bill what this invoice bills from now on: its lines, note and terms (same customer)."
          }
        }
      },
      "SalesRecurringAutoSend": {
        "type": "object",
        "properties": {
          "on": {
            "type": "boolean",
            "description": "true: issue and email each one on the day. false: each one is a draft to check."
          }
        },
        "required": [
          "on"
        ]
      },
      "BooksHmrcConnectionStatus": {
        "type": "string",
        "enum": [
          "connected",
          "needs_reconnect",
          "disconnected",
          "not_connected",
          "not_available"
        ]
      },
      "BooksHmrcConnection": {
        "type": "object",
        "properties": {
          "status": {
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksHmrcConnectionStatus"
              }
            ]
          },
          "environment": {
            "type": [
              "string",
              "null"
            ],
            "description": "sandbox, production, custom, or fake (development)."
          },
          "connectedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "grantExpiresAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "HMRC’s authority lasts 18 months, then you connect again."
          },
          "reconnectSoon": {
            "type": "boolean"
          },
          "message": {
            "type": "string"
          }
        },
        "description": "Tolvi’s authority to file VAT returns for the business at HMRC.",
        "required": [
          "status",
          "environment",
          "connectedAt",
          "grantExpiresAt",
          "reconnectSoon",
          "message"
        ]
      },
      "BooksVatObligationSource": {
        "type": "string",
        "enum": [
          "hmrc",
          "expected"
        ]
      },
      "BooksVatPeriodStatus": {
        "type": "string",
        "enum": [
          "open",
          "filed",
          "overdue",
          "not_ended"
        ]
      },
      "BooksVatDirection": {
        "type": "string",
        "enum": [
          "pay",
          "repay",
          "nil"
        ]
      },
      "BooksVatNextReturn": {
        "type": "object",
        "properties": {
          "periodKey": {
            "type": "string"
          },
          "start": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "end": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "due": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "source": {
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksVatObligationSource"
              }
            ]
          },
          "status": {
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksVatPeriodStatus"
              }
            ]
          },
          "received": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31"
          },
          "box5": {
            "type": "integer",
            "description": "What is owed (or due back) so far, in pence."
          },
          "direction": {
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksVatDirection"
              }
            ]
          }
        },
        "required": [
          "periodKey",
          "start",
          "end",
          "due",
          "source",
          "status",
          "received",
          "box5",
          "direction"
        ]
      },
      "BooksVatSubmissionStatus": {
        "type": "string",
        "enum": [
          "pending",
          "accepted",
          "rejected",
          "unknown"
        ],
        "description": "pending (being sent), accepted, rejected, or unknown (no answer from HMRC: Tolvi checks with HMRC before trying again)."
      },
      "BooksVatBoxes": {
        "type": "object",
        "properties": {
          "box1": {
            "type": "integer"
          },
          "box2": {
            "type": "integer"
          },
          "box3": {
            "type": "integer"
          },
          "box4": {
            "type": "integer"
          },
          "box5": {
            "type": "integer"
          },
          "box6": {
            "type": "integer"
          },
          "box7": {
            "type": "integer"
          },
          "box8": {
            "type": "integer"
          },
          "box9": {
            "type": "integer"
          }
        },
        "description": "The nine boxes in pence. Boxes 6 to 9 are whole pounds (123400 is £1,234). Box 5 is never negative: see `direction`.",
        "required": [
          "box1",
          "box2",
          "box3",
          "box4",
          "box5",
          "box6",
          "box7",
          "box8",
          "box9"
        ]
      },
      "BooksVatSubmission": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "periodKey": {
            "type": "string",
            "example": "26AC"
          },
          "start": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "end": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "due": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31"
          },
          "status": {
            "description": "pending (being sent), accepted, rejected, or unknown (no answer from HMRC: Tolvi checks with HMRC before trying again).",
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksVatSubmissionStatus"
              }
            ]
          },
          "boxes": {
            "$ref": "#/components/schemas/BooksVatBoxes"
          },
          "direction": {
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksVatDirection"
              }
            ]
          },
          "declaredAt": {
            "type": "string",
            "format": "date-time"
          },
          "declaredByName": {
            "type": [
              "string",
              "null"
            ]
          },
          "asAgent": {
            "type": "boolean",
            "description": "Filed by an accountant for the business."
          },
          "processingDate": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "formBundleNumber": {
            "type": [
              "string",
              "null"
            ],
            "example": "123456789012"
          },
          "paymentIndicator": {
            "type": [
              "string",
              "null"
            ],
            "description": "DD: HMRC collects by Direct Debit. BANK: HMRC repays to the bank account it holds."
          },
          "chargeRefNumber": {
            "type": [
              "string",
              "null"
            ]
          },
          "errorMessage": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "description": "A return sent to HMRC, with HMRC’s receipt once accepted. The figures never change.",
        "required": [
          "id",
          "periodKey",
          "start",
          "end",
          "due",
          "status",
          "boxes",
          "direction",
          "declaredAt",
          "declaredByName",
          "asAgent",
          "processingDate",
          "formBundleNumber",
          "paymentIndicator",
          "chargeRefNumber",
          "errorMessage"
        ]
      },
      "BooksVatFindingSeverity": {
        "type": "string",
        "enum": [
          "check",
          "info"
        ]
      },
      "BooksVatProblem": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string"
          },
          "severity": {
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksVatFindingSeverity"
              }
            ]
          },
          "message": {
            "type": "string"
          }
        },
        "required": [
          "code",
          "severity",
          "message"
        ]
      },
      "BooksVatSummary": {
        "type": "object",
        "properties": {
          "registered": {
            "type": "boolean"
          },
          "configured": {
            "type": "boolean"
          },
          "scheme": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/VatScheme"
              },
              {
                "type": "null"
              }
            ]
          },
          "connection": {
            "$ref": "#/components/schemas/BooksHmrcConnection"
          },
          "submissionEnabled": {
            "type": "boolean",
            "description": "Whether returns can be sent to HMRC from this Tolvi (switched on once HMRC approves Tolvi)."
          },
          "submissionMessage": {
            "type": [
              "string",
              "null"
            ]
          },
          "next": {
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksVatNextReturn"
              }
            ]
          },
          "lastFiled": {
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksVatSubmission"
              }
            ]
          },
          "problems": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BooksVatProblem"
            }
          }
        },
        "description": "VAT at a glance: the next deadline, what is owed so far, and anything that needs attention.",
        "required": [
          "registered",
          "configured",
          "scheme",
          "connection",
          "submissionEnabled",
          "submissionMessage",
          "next",
          "lastFiled",
          "problems"
        ]
      },
      "BooksVatStagger": {
        "type": "string",
        "enum": [
          "stagger_1",
          "stagger_2",
          "stagger_3",
          "monthly",
          "annual"
        ]
      },
      "BooksVatAccounting": {
        "type": "string",
        "enum": [
          "accrual",
          "cash"
        ]
      },
      "BooksVatSchemePeriod": {
        "type": "object",
        "properties": {
          "from": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "to": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31"
          },
          "accounting": {
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksVatAccounting"
              }
            ]
          },
          "flatRateSector": {
            "type": [
              "string",
              "null"
            ]
          },
          "flatRateSectorLabel": {
            "type": [
              "string",
              "null"
            ]
          },
          "flatRatePercentBps": {
            "type": [
              "integer",
              "null"
            ],
            "description": "The flat rate percentage in basis points today (the sector’s, less 1% in the first year)."
          },
          "firstYearDiscount": {
            "type": "boolean"
          },
          "annualAccounting": {
            "type": "boolean"
          }
        },
        "required": [
          "from",
          "to",
          "accounting",
          "flatRateSector",
          "flatRateSectorLabel",
          "flatRatePercentBps",
          "firstYearDiscount",
          "annualAccounting"
        ]
      },
      "BooksVatFlatRateSectorOption": {
        "type": "object",
        "properties": {
          "key": {
            "type": "string"
          },
          "label": {
            "type": "string"
          },
          "percentBps": {
            "type": "integer"
          }
        },
        "required": [
          "key",
          "label",
          "percentBps"
        ]
      },
      "BooksVatSettings": {
        "type": "object",
        "properties": {
          "registered": {
            "type": "boolean"
          },
          "configured": {
            "type": "boolean",
            "description": "False until VAT settings are saved (the return periods are then a guess)."
          },
          "vrn": {
            "type": [
              "string",
              "null"
            ]
          },
          "stagger": {
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksVatStagger"
              }
            ]
          },
          "staggerLabel": {
            "type": "string"
          },
          "annualEndMonth": {
            "type": [
              "integer",
              "null"
            ]
          },
          "registeredFrom": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31"
          },
          "scheme": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/VatScheme"
              },
              {
                "type": "null"
              }
            ]
          },
          "schemes": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BooksVatSchemePeriod"
            }
          },
          "filedTo": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31",
            "description": "Returns are filed up to this date: earlier scheme stretches can’t change."
          },
          "flatRateSectors": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BooksVatFlatRateSectorOption"
            }
          }
        },
        "description": "The business’s VAT registration, return periods and schemes.",
        "required": [
          "registered",
          "configured",
          "vrn",
          "stagger",
          "staggerLabel",
          "annualEndMonth",
          "registeredFrom",
          "scheme",
          "schemes",
          "filedTo",
          "flatRateSectors"
        ]
      },
      "BooksVatFlatRateSector": {
        "type": "string",
        "enum": [
          "accountancy-or-book-keeping",
          "advertising",
          "agricultural-services",
          "any-other-activity",
          "architect-engineer-or-surveyor",
          "boarding-or-care-of-animals",
          "business-services",
          "catering",
          "computer-and-it-consultancy",
          "computer-repair",
          "entertainment-or-journalism",
          "estate-agency-or-property-management",
          "farming-or-agriculture",
          "film-radio-tv-or-video-production",
          "financial-services",
          "forestry-or-fishing",
          "general-building-or-construction",
          "hairdressing-or-beauty",
          "hiring-or-renting-goods",
          "hotel-or-accommodation",
          "investigation-or-security",
          "labour-only-building-or-construction",
          "laundry-or-dry-cleaning",
          "lawyer-or-legal-services",
          "library-archive-museum-or-cultural",
          "management-consultancy",
          "manufacturing-fabricated-metal-products",
          "manufacturing-food",
          "manufacturing-other",
          "manufacturing-yarn-textiles-or-clothing",
          "membership-organisation",
          "mining-or-quarrying",
          "packaging",
          "photography",
          "post-offices",
          "printing",
          "publishing",
          "pubs",
          "real-estate-other",
          "repairing-personal-or-household-goods",
          "repairing-vehicles",
          "retailing-food-confectionery-tobacco-newspapers-childrens-clothing",
          "retailing-pharmaceuticals-medical-cosmetics-toiletries",
          "retailing-other",
          "retailing-vehicles-or-fuel",
          "secretarial-services",
          "social-work",
          "sport-or-recreation",
          "transport-or-storage",
          "travel-agency",
          "veterinary-medicine",
          "wholesaling-agricultural-products",
          "wholesaling-food",
          "wholesaling-other"
        ]
      },
      "BooksVatFlatRateChoice": {
        "type": "object",
        "properties": {
          "sector": {
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksVatFlatRateSector"
              }
            ]
          },
          "firstYearDiscount": {
            "type": "boolean",
            "description": "The 1% reduction in the first year of VAT registration (Notice 733 para 4.7)."
          }
        },
        "required": [
          "sector",
          "firstYearDiscount"
        ]
      },
      "BooksUpdateVatSettings": {
        "type": "object",
        "properties": {
          "vrn": {
            "type": "string",
            "example": "123456782",
            "description": "The 9-digit VAT registration number, with or without GB. Its check digits are checked."
          },
          "stagger": {
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksVatStagger"
              }
            ]
          },
          "annualEndMonth": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Annual accounting: the month the VAT year ends."
          },
          "registeredFrom": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31",
            "description": "The effective date of registration."
          },
          "accounting": {
            "description": "accrual (invoice dates) or cash (when money moves, Notice 731).",
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksVatAccounting"
              }
            ]
          },
          "flatRate": {
            "description": "The flat rate scheme; leave it out (or null) when not on it.",
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksVatFlatRateChoice"
              }
            ]
          },
          "annualAccounting": {
            "type": "boolean"
          },
          "schemeFrom": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          }
        },
        "description": "The business’s VAT registration and scheme. Changing the scheme starts a new stretch from `schemeFrom`; stretches covering a filed return never change.",
        "required": [
          "vrn",
          "stagger",
          "registeredFrom",
          "accounting"
        ]
      },
      "BooksVatPeriod": {
        "type": "object",
        "properties": {
          "periodKey": {
            "type": "string"
          },
          "start": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "end": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "due": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "source": {
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksVatObligationSource"
              }
            ]
          },
          "status": {
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksVatPeriodStatus"
              }
            ]
          },
          "received": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31"
          }
        },
        "description": "A VAT period: HMRC’s obligation, or (not connected yet) the period expected from the return periods.",
        "required": [
          "periodKey",
          "start",
          "end",
          "due",
          "source",
          "status",
          "received"
        ]
      },
      "BooksVatPeriods": {
        "type": "object",
        "properties": {
          "periods": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BooksVatPeriod"
            }
          },
          "fetchedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "When HMRC was last asked (null: never, the periods are expected ones)."
          }
        },
        "required": [
          "periods",
          "fetchedAt"
        ]
      },
      "BooksVatPeriodSource": {
        "type": "string",
        "enum": [
          "hmrc",
          "filed",
          "expected"
        ],
        "description": "hmrc (an obligation), filed, or expected (from the return periods; not connected to HMRC yet)."
      },
      "BooksVatReturnStatus": {
        "type": "string",
        "enum": [
          "open",
          "filed",
          "not_ended",
          "sending"
        ]
      },
      "BooksVatBoxesInPence": {
        "type": "object",
        "properties": {
          "box6": {
            "type": "integer"
          },
          "box7": {
            "type": "integer"
          },
          "box8": {
            "type": "integer"
          },
          "box9": {
            "type": "integer"
          }
        },
        "required": [
          "box6",
          "box7",
          "box8",
          "box9"
        ]
      },
      "BooksVatFlatRateBucket": {
        "type": "object",
        "properties": {
          "bps": {
            "type": "integer"
          },
          "turnoverGrossPence": {
            "type": "integer"
          },
          "vatPence": {
            "type": "integer"
          },
          "firstYearReduction": {
            "type": "boolean"
          }
        },
        "required": [
          "bps",
          "turnoverGrossPence",
          "vatPence",
          "firstYearReduction"
        ]
      },
      "BooksVatFlatRateSummary": {
        "type": "object",
        "properties": {
          "turnoverGrossPence": {
            "type": "integer"
          },
          "limitedCost": {
            "type": "boolean"
          },
          "explanation": {
            "type": "string"
          },
          "buckets": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BooksVatFlatRateBucket"
            }
          }
        },
        "required": [
          "turnoverGrossPence",
          "limitedCost",
          "explanation",
          "buckets"
        ]
      },
      "BooksVatFinding": {
        "type": "object",
        "properties": {
          "kind": {
            "type": "string",
            "example": "missing_receipt"
          },
          "severity": {
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksVatFindingSeverity"
              }
            ]
          },
          "title": {
            "type": "string"
          },
          "detail": {
            "type": "string"
          },
          "box": {
            "type": [
              "integer",
              "null"
            ]
          },
          "lineRefs": {
            "description": "The lines it is about, as `seq:lineIndex`.",
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        },
        "description": "Something worth looking at before filing. A suggestion only: nothing is changed.",
        "required": [
          "kind",
          "severity",
          "title",
          "detail",
          "box",
          "lineRefs"
        ]
      },
      "BooksVatErrorNotification": {
        "type": "object",
        "properties": {
          "netErrorPence": {
            "type": "integer",
            "description": "What the corrections do to box 5, in pence: positive is more owed to HMRC."
          },
          "limitPence": {
            "type": "integer",
            "description": "The limit for this return, in pence."
          },
          "box6Pence": {
            "type": "integer"
          },
          "message": {
            "type": "string"
          },
          "source": {
            "type": "string",
            "description": "The legislation or HMRC notice."
          },
          "lineRefs": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        },
        "description": "Corrections to earlier returns over the Notice 700/45 limit. They are not on this return: the business must tell HMRC separately (form VAT652).",
        "required": [
          "netErrorPence",
          "limitPence",
          "box6Pence",
          "message",
          "source",
          "lineRefs"
        ]
      },
      "BooksVatCheck": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "returnHash": {
            "type": "string"
          },
          "current": {
            "type": "boolean"
          },
          "summary": {
            "type": "string"
          },
          "findings": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BooksVatFinding"
            }
          },
          "ai": {
            "type": "boolean"
          }
        },
        "description": "The check before filing: Tolvi’s own checks and Tolvi AI’s suggestions. It never changes the return.",
        "required": [
          "id",
          "createdAt",
          "returnHash",
          "current",
          "summary",
          "findings",
          "ai"
        ]
      },
      "BooksVatDeclaration": {
        "type": "object",
        "properties": {
          "version": {
            "type": "string"
          },
          "text": {
            "type": "string"
          },
          "asAgent": {
            "type": "boolean"
          }
        },
        "description": "The legal declaration to show and accept before filing (HMRC’s wording).",
        "required": [
          "version",
          "text",
          "asAgent"
        ]
      },
      "BooksVatReturn": {
        "type": "object",
        "properties": {
          "periodKey": {
            "type": "string",
            "example": "26AC"
          },
          "start": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "end": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "due": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31"
          },
          "source": {
            "description": "hmrc (an obligation), filed, or expected (from the return periods; not connected to HMRC yet).",
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksVatPeriodSource"
              }
            ]
          },
          "status": {
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksVatReturnStatus"
              }
            ]
          },
          "boxes": {
            "$ref": "#/components/schemas/BooksVatBoxes"
          },
          "direction": {
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksVatDirection"
              }
            ]
          },
          "boxesInPence": {
            "$ref": "#/components/schemas/BooksVatBoxesInPence"
          },
          "lineCount": {
            "type": "integer"
          },
          "lateCount": {
            "type": "integer",
            "description": "Payments brought in from a period already filed (cash accounting)."
          },
          "flatRate": {
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksVatFlatRateSummary"
              }
            ]
          },
          "findings": {
            "description": "Tolvi’s own checks (no AI).",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BooksVatFinding"
            }
          },
          "errorNotification": {
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksVatErrorNotification"
              }
            ]
          },
          "takenBackCount": {
            "type": "integer",
            "description": "Payments undone after an earlier return included them, taken back on this one."
          },
          "returnHash": {
            "type": "string",
            "description": "Send it back when filing: the figures filed are the ones reviewed."
          },
          "check": {
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksVatCheck"
              }
            ]
          },
          "submission": {
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksVatSubmission"
              }
            ]
          },
          "canSubmit": {
            "type": "boolean"
          },
          "cannotSubmitReason": {
            "type": [
              "string",
              "null"
            ]
          },
          "declaration": {
            "$ref": "#/components/schemas/BooksVatDeclaration"
          }
        },
        "description": "A VAT return for one period: worked out from the books until it is filed, then the figures HMRC accepted.",
        "required": [
          "periodKey",
          "start",
          "end",
          "due",
          "source",
          "status",
          "boxes",
          "direction",
          "boxesInPence",
          "lineCount",
          "lateCount",
          "flatRate",
          "findings",
          "errorNotification",
          "takenBackCount",
          "returnHash",
          "check",
          "submission",
          "canSubmit",
          "cannotSubmitReason",
          "declaration"
        ]
      },
      "BooksVatBoxAmount": {
        "type": "object",
        "properties": {
          "box": {
            "type": "integer"
          },
          "amountPence": {
            "type": "integer"
          }
        },
        "required": [
          "box",
          "amountPence"
        ]
      },
      "BooksVatReturnLine": {
        "type": "object",
        "properties": {
          "ref": {
            "type": "string",
            "example": "12:0",
            "description": "`seq:lineIndex`"
          },
          "lineId": {
            "type": "string",
            "format": "uuid"
          },
          "entryId": {
            "type": "string",
            "format": "uuid"
          },
          "entrySeq": {
            "type": "integer"
          },
          "date": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "taxPoint": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "accountingDate": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31",
            "description": "The date that put it in this return (the tax point, or when it was paid under cash accounting)."
          },
          "description": {
            "type": "string"
          },
          "accountCode": {
            "type": "string"
          },
          "accountName": {
            "type": "string"
          },
          "accountOwnerName": {
            "type": "string"
          },
          "vatCodeId": {
            "type": "string"
          },
          "side": {
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksVatSide"
              }
            ]
          },
          "netPence": {
            "type": "integer"
          },
          "vatPence": {
            "type": "integer"
          },
          "boxes": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BooksVatBoxAmount"
            }
          },
          "flatRateTurnoverPence": {
            "type": "integer"
          },
          "explanation": {
            "type": "string"
          },
          "late": {
            "type": "boolean"
          },
          "settlementId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "hasReceipt": {
            "type": "boolean"
          }
        },
        "description": "One line (or one payment of a line, under cash accounting) in a return, and what it adds to each box.",
        "required": [
          "ref",
          "lineId",
          "entryId",
          "entrySeq",
          "date",
          "taxPoint",
          "accountingDate",
          "description",
          "accountCode",
          "accountName",
          "accountOwnerName",
          "vatCodeId",
          "side",
          "netPence",
          "vatPence",
          "boxes",
          "flatRateTurnoverPence",
          "explanation",
          "late",
          "settlementId",
          "hasReceipt"
        ]
      },
      "BooksVatReturnLines": {
        "type": "object",
        "properties": {
          "box": {
            "type": [
              "integer",
              "null"
            ]
          },
          "totalPence": {
            "type": "integer",
            "description": "The box’s total, in pence."
          },
          "title": {
            "type": "string"
          },
          "meaning": {
            "type": "string"
          },
          "lines": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BooksVatReturnLine"
            }
          }
        },
        "required": [
          "box",
          "totalPence",
          "title",
          "meaning",
          "lines"
        ]
      },
      "BooksVatRecordErrorNotification": {
        "type": "object",
        "properties": {
          "notifiedOn": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "reference": {
            "type": "string"
          }
        },
        "description": "The business has told HMRC about corrections over the limit: they stay off every return from now on.",
        "required": [
          "notifiedOn"
        ]
      },
      "BooksVatClientFacts": {
        "type": "object",
        "properties": {
          "deviceId": {
            "type": "string",
            "format": "uuid",
            "description": "A UUID kept on this device (local storage)."
          },
          "userAgent": {
            "type": "string",
            "description": "navigator.userAgent"
          },
          "screens": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "width": {
                  "type": "integer"
                },
                "height": {
                  "type": "integer"
                },
                "scalingFactor": {
                  "type": "number"
                },
                "colourDepth": {
                  "type": "integer"
                }
              },
              "required": [
                "width",
                "height",
                "scalingFactor",
                "colourDepth"
              ]
            }
          },
          "windowWidth": {
            "type": "integer"
          },
          "windowHeight": {
            "type": "integer"
          },
          "timezone": {
            "type": "string",
            "example": "UTC+01:00"
          },
          "appVersion": {
            "type": "string"
          }
        },
        "description": "What the browser knows about itself, for HMRC’s fraud prevention headers (Gov-Client-*). Send it with every request that reaches HMRC.",
        "required": [
          "deviceId",
          "userAgent",
          "screens",
          "windowWidth",
          "windowHeight",
          "timezone"
        ]
      },
      "BooksSubmitVatReturn": {
        "type": "object",
        "properties": {
          "returnHash": {
            "type": "string"
          },
          "declaration": {
            "type": "object",
            "properties": {
              "accepted": {
                "type": "boolean",
                "enum": [
                  true
                ]
              },
              "version": {
                "type": "string"
              }
            },
            "required": [
              "accepted",
              "version"
            ]
          },
          "checkId": {
            "type": "string",
            "format": "uuid"
          },
          "clientFacts": {
            "$ref": "#/components/schemas/BooksVatClientFacts"
          }
        },
        "description": "File the return. The person accepts HMRC’s declaration; `returnHash` must be the preview’s, so what was reviewed is what is filed.",
        "required": [
          "returnHash",
          "clientFacts"
        ]
      },
      "BooksVatSubmissions": {
        "type": "object",
        "properties": {
          "submissions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BooksVatSubmission"
            }
          }
        },
        "required": [
          "submissions"
        ]
      },
      "BooksVatLiability": {
        "type": "object",
        "properties": {
          "periodStart": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31"
          },
          "periodEnd": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31"
          },
          "type": {
            "type": "string",
            "example": "VAT Return Debit Charge"
          },
          "originalAmountPence": {
            "type": "integer"
          },
          "outstandingAmountPence": {
            "type": [
              "integer",
              "null"
            ]
          },
          "due": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31"
          }
        },
        "required": [
          "periodStart",
          "periodEnd",
          "type",
          "originalAmountPence",
          "outstandingAmountPence",
          "due"
        ]
      },
      "BooksVatPayment": {
        "type": "object",
        "properties": {
          "amountPence": {
            "type": "integer"
          },
          "received": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31"
          }
        },
        "required": [
          "amountPence",
          "received"
        ]
      },
      "BooksVatPaymentsAndLiabilities": {
        "type": "object",
        "properties": {
          "liabilities": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BooksVatLiability"
            }
          },
          "payments": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BooksVatPayment"
            }
          },
          "fetchedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          }
        },
        "description": "What HMRC says is owed and has been paid, as last fetched.",
        "required": [
          "liabilities",
          "payments",
          "fetchedAt"
        ]
      },
      "BooksHmrcAuthorize": {
        "type": "object",
        "properties": {
          "url": {
            "type": "string",
            "description": "Send the person here to sign in to HMRC and give Tolvi authority."
          }
        },
        "required": [
          "url"
        ]
      },
      "BooksHmrcCallback": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string"
          },
          "state": {
            "type": "string"
          }
        },
        "required": [
          "code",
          "state"
        ]
      },
      "BooksVatWithClientFacts": {
        "type": "object",
        "properties": {
          "clientFacts": {
            "$ref": "#/components/schemas/BooksVatClientFacts"
          }
        },
        "required": [
          "clientFacts"
        ]
      },
      "BooksInboxViewer": {
        "type": "object",
        "properties": {
          "canAct": {
            "type": "boolean",
            "description": "False for an accountant whose link only lets them see the books."
          },
          "accountant": {
            "type": "boolean",
            "description": "An accountant working through the practice link."
          },
          "canAutoPost": {
            "type": "boolean",
            "description": "May let a rule post without asking (the business’s owners and admins, signed in)."
          },
          "readOnlyReason": {
            "type": [
              "string",
              "null"
            ],
            "description": "Why the viewer can’t act, in plain English."
          }
        },
        "description": "Who is looking, and whether they can act on the inbox.",
        "required": [
          "canAct",
          "accountant",
          "canAutoPost",
          "readOnlyReason"
        ]
      },
      "BooksInboxCounts": {
        "type": "object",
        "properties": {
          "total": {
            "type": "integer"
          },
          "questions": {
            "type": "integer"
          },
          "suggested": {
            "type": "integer"
          },
          "matched": {
            "type": "integer"
          },
          "tasks": {
            "type": "integer"
          },
          "ruleOffers": {
            "type": "integer"
          }
        },
        "required": [
          "total",
          "questions",
          "suggested",
          "matched",
          "tasks",
          "ruleOffers"
        ]
      },
      "BooksInboxAiState": {
        "type": "string",
        "enum": [
          "on",
          "waiting"
        ]
      },
      "BooksInboxAi": {
        "type": "object",
        "properties": {
          "state": {
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksInboxAiState"
              }
            ]
          },
          "allowance": {
            "type": "integer",
            "description": "AI suggestions included this month."
          },
          "used": {
            "type": "integer"
          },
          "resetsOn": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31",
            "description": "When the allowance starts again."
          },
          "waiting": {
            "type": "integer",
            "description": "Lines waiting for Tolvi AI."
          },
          "message": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "description": "Tolvi AI in the inbox this month (fair use, D-83): past the allowance it waits, and nothing is charged.",
        "required": [
          "state",
          "allowance",
          "used",
          "resetsOn",
          "waiting",
          "message"
        ]
      },
      "BooksInboxChoice": {
        "type": "object",
        "properties": {
          "label": {
            "type": "string"
          },
          "asSuggested": {
            "type": "boolean",
            "description": "Confirm as Tolvi suggested (a copy set aside, a match)."
          },
          "categorisation": {
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksBankCategorisation"
              }
            ]
          }
        },
        "description": "One answer to a question.",
        "required": [
          "label",
          "asSuggested",
          "categorisation"
        ]
      },
      "BooksInboxLine": {
        "type": "object",
        "properties": {
          "line": {
            "$ref": "#/components/schemas/BooksBankLine"
          },
          "bankAccountName": {
            "type": [
              "string",
              "null"
            ]
          },
          "sourceLabel": {
            "type": "string",
            "description": "“From your rule”, “You usually choose this”, “Tolvi AI suggests”, “Matched”…"
          },
          "question": {
            "type": [
              "string",
              "null"
            ],
            "description": "For a question: what Tolvi asks, in plain English."
          },
          "choices": {
            "description": "For a question: two or three likely answers.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BooksInboxChoice"
            }
          }
        },
        "description": "A bank line in the inbox, with where its suggestion came from.",
        "required": [
          "line",
          "bankAccountName",
          "sourceLabel",
          "question",
          "choices"
        ]
      },
      "BooksInboxDirection": {
        "type": "string",
        "enum": [
          "in",
          "out"
        ]
      },
      "BooksInboxGroup": {
        "type": "object",
        "properties": {
          "key": {
            "type": "string"
          },
          "label": {
            "type": "string"
          },
          "payee": {
            "type": "string"
          },
          "direction": {
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksInboxDirection"
              }
            ]
          },
          "categorisation": {
            "$ref": "#/components/schemas/BooksBankCategorisation"
          },
          "sourceLabel": {
            "type": "string"
          },
          "reasons": {
            "description": "The “Why?” of the newest line.",
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "totalPence": {
            "type": "integer"
          },
          "lineIds": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "lines": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BooksInboxLine"
            }
          }
        },
        "description": "Suggested lines from one payee with the same suggestion: one tap confirms them all.",
        "required": [
          "key",
          "label",
          "payee",
          "direction",
          "categorisation",
          "sourceLabel",
          "reasons",
          "totalPence",
          "lineIds",
          "lines"
        ]
      },
      "BooksInboxDecider": {
        "type": "string",
        "enum": [
          "owner",
          "accountant"
        ]
      },
      "BooksInboxRuleOffer": {
        "type": "object",
        "properties": {
          "merchantKey": {
            "type": "string"
          },
          "merchant": {
            "type": "string"
          },
          "direction": {
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksInboxDirection"
              }
            ]
          },
          "question": {
            "type": "string"
          },
          "reason": {
            "type": "string"
          },
          "ruleText": {
            "type": "string",
            "description": "The rule in plain words."
          },
          "categorisation": {
            "$ref": "#/components/schemas/BooksBankCategorisation"
          },
          "by": {
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksInboxDecider"
              }
            ]
          }
        },
        "description": "“Do this every time for Screwfix?”, offered after two identical corrections (or one by the accountant).",
        "required": [
          "merchantKey",
          "merchant",
          "direction",
          "question",
          "reason",
          "ruleText",
          "categorisation",
          "by"
        ]
      },
      "BooksInboxTaskKind": {
        "type": "string",
        "enum": [
          "receipt",
          "reminder",
          "invoice",
          "vat",
          "bank_consent",
          "hmrc_consent"
        ]
      },
      "BooksInboxTaskTone": {
        "type": "string",
        "enum": [
          "info",
          "warning",
          "danger"
        ]
      },
      "BooksInboxTask": {
        "type": "object",
        "properties": {
          "kind": {
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksInboxTaskKind"
              }
            ]
          },
          "id": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "detail": {
            "type": [
              "string",
              "null"
            ]
          },
          "amountPence": {
            "type": [
              "integer",
              "null"
            ]
          },
          "date": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31"
          },
          "path": {
            "description": "Where to go, relative to the Books area (e.g. [\"sales\", \"invoices\", \"<id>\"]).",
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "query": {
            "type": [
              "object",
              "null"
            ],
            "additionalProperties": {
              "type": "string"
            },
            "description": "Query parameters for the link."
          },
          "ownerOnly": {
            "type": "boolean",
            "description": "Only the business’s own people can do this (an accountant sees it but can’t)."
          },
          "tone": {
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksInboxTaskTone"
              }
            ]
          }
        },
        "description": "Something else that needs the owner: a receipt to check, a reminder to approve, an invoice to chase, VAT, or a connection running out.",
        "required": [
          "kind",
          "id",
          "title",
          "detail",
          "amountPence",
          "date",
          "path",
          "query",
          "ownerOnly",
          "tone"
        ]
      },
      "BooksInboxSorted": {
        "type": "object",
        "properties": {
          "count": {
            "type": "integer"
          },
          "since": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          }
        },
        "description": "Lines your rules posted without a tap in the last 7 days (in the activity, each with Undo).",
        "required": [
          "count",
          "since"
        ]
      },
      "BooksInbox": {
        "type": "object",
        "properties": {
          "viewer": {
            "$ref": "#/components/schemas/BooksInboxViewer"
          },
          "counts": {
            "$ref": "#/components/schemas/BooksInboxCounts"
          },
          "ai": {
            "$ref": "#/components/schemas/BooksInboxAi"
          },
          "questions": {
            "description": "Tolvi isn’t sure: answer in a tap.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BooksInboxLine"
            }
          },
          "groups": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BooksInboxGroup"
            }
          },
          "suggested": {
            "description": "Suggested lines not in a group.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BooksInboxLine"
            }
          },
          "matched": {
            "description": "Paid invoices, receipts found and transfers between your accounts.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BooksInboxLine"
            }
          },
          "ruleOffers": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BooksInboxRuleOffer"
            }
          },
          "tasks": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BooksInboxTask"
            }
          },
          "sortedByRules": {
            "$ref": "#/components/schemas/BooksInboxSorted"
          }
        },
        "description": "Everything that needs the owner, most of it already sorted, each with a “Why?”. Nothing in it posts until a person confirms (or the owner’s own rule does).",
        "required": [
          "viewer",
          "counts",
          "ai",
          "questions",
          "groups",
          "suggested",
          "matched",
          "ruleOffers",
          "tasks",
          "sortedByRules"
        ]
      },
      "BooksInboxUndoLines": {
        "type": "object",
        "properties": {
          "lineIds": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        },
        "required": [
          "lineIds"
        ]
      },
      "BooksInboxConfidence": {
        "type": "string",
        "enum": [
          "high",
          "medium",
          "low"
        ]
      },
      "BooksInboxAiStatus": {
        "type": "string",
        "enum": [
          "proposed",
          "accepted",
          "discarded"
        ]
      },
      "BooksInboxAiDetail": {
        "type": "object",
        "properties": {
          "suggestionId": {
            "type": "string",
            "format": "uuid"
          },
          "model": {
            "type": "string"
          },
          "promptVersion": {
            "type": "string"
          },
          "confidence": {
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksInboxConfidence"
              }
            ]
          },
          "status": {
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksInboxAiStatus"
              }
            ]
          },
          "at": {
            "type": "string",
            "format": "date-time"
          }
        },
        "description": "Tolvi AI’s part in a suggestion.",
        "required": [
          "suggestionId",
          "model",
          "promptVersion",
          "confidence",
          "status",
          "at"
        ]
      },
      "BooksInboxMemory": {
        "type": "object",
        "properties": {
          "label": {
            "type": "string"
          },
          "times": {
            "type": "integer"
          }
        },
        "description": "What this business chose before for the payee.",
        "required": [
          "label",
          "times"
        ]
      },
      "BooksInboxActivityAction": {
        "type": "string",
        "enum": [
          "confirmed",
          "changed",
          "answered",
          "set_aside",
          "posted_by_rule",
          "undone"
        ]
      },
      "BooksInboxDeciderKind": {
        "type": "string",
        "enum": [
          "owner",
          "accountant",
          "rule"
        ]
      },
      "BooksInboxPerson": {
        "type": "object",
        "properties": {
          "kind": {
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksInboxDeciderKind"
              }
            ]
          },
          "name": {
            "type": "string"
          },
          "firmName": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "description": "Who decided: a person at the business, an accountant (with their firm) or a rule.",
        "required": [
          "kind",
          "name",
          "firmName"
        ]
      },
      "BooksInboxActivityItem": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "lineId": {
            "type": "string",
            "format": "uuid"
          },
          "at": {
            "type": "string",
            "format": "date-time"
          },
          "action": {
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksInboxActivityAction"
              }
            ]
          },
          "by": {
            "$ref": "#/components/schemas/BooksInboxPerson"
          },
          "payee": {
            "type": [
              "string",
              "null"
            ]
          },
          "amountPence": {
            "type": "integer"
          },
          "what": {
            "type": [
              "string",
              "null"
            ],
            "description": "What it went in as."
          },
          "undoable": {
            "type": "boolean",
            "description": "Still stands and can be undone."
          }
        },
        "description": "One decision: who confirmed, changed, set aside or undid what.",
        "required": [
          "id",
          "lineId",
          "at",
          "action",
          "by",
          "payee",
          "amountPence",
          "what",
          "undoable"
        ]
      },
      "BooksInboxWhy": {
        "type": "object",
        "properties": {
          "item": {
            "$ref": "#/components/schemas/BooksInboxLine"
          },
          "ai": {
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksInboxAiDetail"
              }
            ]
          },
          "memory": {
            "description": "Most chosen first.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BooksInboxMemory"
            }
          },
          "history": {
            "description": "Every decision on this line, newest first.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BooksInboxActivityItem"
            }
          }
        },
        "description": "The “Why?” sheet: where a suggestion came from, what it rests on, and who has decided what on this line.",
        "required": [
          "item",
          "ai",
          "memory",
          "history"
        ]
      },
      "BooksInboxActivity": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BooksInboxActivityItem"
            }
          }
        },
        "required": [
          "items"
        ]
      },
      "BooksInboxAcceptRuleOffer": {
        "type": "object",
        "properties": {
          "merchantKey": {
            "type": "string"
          },
          "direction": {
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksInboxDirection"
              }
            ]
          },
          "postWithoutAsking": {
            "type": "boolean",
            "description": "Post matching lines without a tap. The business’s owners and admins only, signed in."
          }
        },
        "required": [
          "merchantKey",
          "direction"
        ]
      },
      "BooksInboxRuleCreated": {
        "type": "object",
        "properties": {
          "ruleId": {
            "type": "string",
            "format": "uuid"
          },
          "description": {
            "type": "string"
          },
          "postWithoutAsking": {
            "type": "boolean"
          }
        },
        "required": [
          "ruleId",
          "description",
          "postWithoutAsking"
        ]
      },
      "BooksInboxDeclineAnswer": {
        "type": "string",
        "enum": [
          "not_now",
          "ask_each_time"
        ]
      },
      "BooksInboxDeclineRuleOffer": {
        "type": "object",
        "properties": {
          "merchantKey": {
            "type": "string"
          },
          "direction": {
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksInboxDirection"
              }
            ]
          },
          "answer": {
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksInboxDeclineAnswer"
              }
            ]
          }
        },
        "required": [
          "merchantKey",
          "direction",
          "answer"
        ]
      },
      "BooksPurchasesCreditor": {
        "type": "object",
        "properties": {
          "supplierId": {
            "type": "string",
            "format": "uuid"
          },
          "supplierName": {
            "type": "string"
          },
          "owedPence": {
            "type": "integer"
          },
          "overduePence": {
            "type": "integer"
          },
          "bills": {
            "type": "integer"
          }
        },
        "description": "One supplier the business owes.",
        "required": [
          "supplierId",
          "supplierName",
          "owedPence",
          "overduePence",
          "bills"
        ]
      },
      "BooksPurchasesSummary": {
        "type": "object",
        "properties": {
          "asAt": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "owedPence": {
            "type": "integer"
          },
          "overduePence": {
            "type": "integer"
          },
          "dueSoonPence": {
            "type": "integer",
            "description": "What falls due in the next 7 days."
          },
          "unpaidBills": {
            "type": "integer"
          },
          "overdueBills": {
            "type": "integer"
          },
          "drafts": {
            "type": "integer"
          },
          "creditors": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BooksPurchasesCreditor"
            }
          }
        },
        "description": "What the business owes as at today.",
        "required": [
          "asAt",
          "owedPence",
          "overduePence",
          "dueSoonPence",
          "unpaidBills",
          "overdueBills",
          "drafts",
          "creditors"
        ]
      },
      "BooksSupplier": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "email": {
            "type": [
              "string",
              "null"
            ]
          },
          "addressLines": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "postcode": {
            "type": [
              "string",
              "null"
            ]
          },
          "vatNumber": {
            "type": [
              "string",
              "null"
            ]
          },
          "paymentTermsDays": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Days to pay; null means 30 days unless a bill gives a due date."
          },
          "defaultAccountId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid",
            "description": "The account used on the last bill, to fill in the next one."
          },
          "defaultVatCode": {
            "type": [
              "string",
              "null"
            ]
          },
          "owedPence": {
            "type": "integer",
            "description": "What is still owed, in pence."
          },
          "openBills": {
            "type": "integer"
          },
          "archived": {
            "type": "boolean"
          }
        },
        "description": "A business this business buys from.",
        "required": [
          "id",
          "name",
          "email",
          "addressLines",
          "postcode",
          "vatNumber",
          "paymentTermsDays",
          "defaultAccountId",
          "defaultVatCode",
          "owedPence",
          "openBills",
          "archived"
        ]
      },
      "BooksSupplierList": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BooksSupplier"
            }
          }
        },
        "required": [
          "items"
        ]
      },
      "BooksSupplierInput": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "maxLength": 200
          },
          "email": {
            "type": [
              "string",
              "null"
            ]
          },
          "addressLines": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "postcode": {
            "type": [
              "string",
              "null"
            ]
          },
          "vatNumber": {
            "type": [
              "string",
              "null"
            ]
          },
          "paymentTermsDays": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 0,
            "maximum": 365
          }
        },
        "required": [
          "name"
        ]
      },
      "BooksSupplierPatch": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "maxLength": 200
          },
          "email": {
            "type": [
              "string",
              "null"
            ]
          },
          "addressLines": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "postcode": {
            "type": [
              "string",
              "null"
            ]
          },
          "vatNumber": {
            "type": [
              "string",
              "null"
            ]
          },
          "paymentTermsDays": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 0,
            "maximum": 365
          },
          "archived": {
            "type": "boolean"
          }
        }
      },
      "BooksBillKind": {
        "type": "string",
        "enum": [
          "bill",
          "supplier_credit"
        ]
      },
      "BooksBillState": {
        "type": "string",
        "enum": [
          "draft",
          "posted"
        ]
      },
      "BooksBillStatus": {
        "type": "string",
        "enum": [
          "draft",
          "to_pay",
          "part_paid",
          "overdue",
          "paid",
          "void"
        ]
      },
      "BooksBill": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "kind": {
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksBillKind"
              }
            ]
          },
          "state": {
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksBillState"
              }
            ]
          },
          "status": {
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksBillStatus"
              }
            ]
          },
          "supplierId": {
            "type": "string",
            "format": "uuid"
          },
          "supplierName": {
            "type": "string"
          },
          "reference": {
            "type": [
              "string",
              "null"
            ],
            "description": "The supplier’s own invoice or credit note number."
          },
          "billDate": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31"
          },
          "dueDate": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31"
          },
          "notes": {
            "type": [
              "string",
              "null"
            ]
          },
          "reason": {
            "type": [
              "string",
              "null"
            ]
          },
          "creditsId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "opening": {
            "type": "boolean",
            "description": "Brought forward with the starting balances: dated before the books start, with no VAT breakdown."
          },
          "receiptId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid",
            "description": "The photo or PDF this came from (GET /books/receipts/{id}/image)."
          },
          "netPence": {
            "type": "integer"
          },
          "vatPence": {
            "type": "integer"
          },
          "grossPence": {
            "type": "integer"
          },
          "paidPence": {
            "type": "integer"
          },
          "creditedPence": {
            "type": "integer"
          },
          "outstandingPence": {
            "type": "integer"
          },
          "overpaidPence": {
            "type": "integer"
          },
          "daysOverdue": {
            "type": "integer"
          },
          "ledgerEntryId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "postedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          }
        },
        "description": "A bill or supplier credit. What is owed is worked from its payments and credits as at today, never stored.",
        "required": [
          "id",
          "kind",
          "state",
          "status",
          "supplierId",
          "supplierName",
          "reference",
          "billDate",
          "dueDate",
          "notes",
          "reason",
          "creditsId",
          "opening",
          "receiptId",
          "netPence",
          "vatPence",
          "grossPence",
          "paidPence",
          "creditedPence",
          "outstandingPence",
          "overpaidPence",
          "daysOverdue",
          "ledgerEntryId",
          "createdAt",
          "postedAt"
        ]
      },
      "BooksBillList": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BooksBill"
            }
          }
        },
        "required": [
          "items"
        ]
      },
      "BooksBillLineInput": {
        "type": "object",
        "properties": {
          "description": {
            "type": "string",
            "maxLength": 500
          },
          "accountId": {
            "type": "string",
            "format": "uuid",
            "description": "A cost or asset account."
          },
          "netPence": {
            "type": "integer"
          },
          "vatCode": {
            "type": "string",
            "example": "S20"
          },
          "vatPence": {
            "type": "integer",
            "description": "The VAT on the bill; worked from the rate at the bill’s date when left out."
          }
        },
        "required": [
          "description",
          "accountId",
          "netPence",
          "vatCode"
        ]
      },
      "BooksCreateBill": {
        "type": "object",
        "properties": {
          "supplierId": {
            "type": "string",
            "format": "uuid"
          },
          "supplierName": {
            "type": "string",
            "maxLength": 200
          },
          "reference": {
            "type": [
              "string",
              "null"
            ],
            "description": "The supplier’s own invoice number."
          },
          "billDate": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31"
          },
          "dueDate": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31",
            "description": "Left out: the supplier’s terms, or 30 days."
          },
          "notes": {
            "type": [
              "string",
              "null"
            ]
          },
          "lines": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BooksBillLineInput"
            }
          },
          "receiptId": {
            "type": "string",
            "format": "uuid",
            "description": "The receipt or bill photo this came from."
          },
          "post": {
            "type": "boolean",
            "description": "Add it to the books straight away."
          }
        },
        "description": "A supplierId, or a supplierName to find or add one."
      },
      "BooksBillLine": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "description": {
            "type": "string"
          },
          "accountId": {
            "type": "string",
            "format": "uuid"
          },
          "accountName": {
            "type": "string"
          },
          "netPence": {
            "type": "integer"
          },
          "vatCode": {
            "type": "string",
            "example": "S20"
          },
          "vatPence": {
            "type": "integer"
          }
        },
        "description": "A line as on the bill. A credit’s lines are positive too: its kind gives the direction.",
        "required": [
          "id",
          "description",
          "accountId",
          "accountName",
          "netPence",
          "vatCode",
          "vatPence"
        ]
      },
      "BooksBillPaymentMethod": {
        "type": "string",
        "enum": [
          "bank_transfer",
          "card",
          "cash",
          "cheque",
          "other"
        ]
      },
      "BooksBillPayment": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "paidOn": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "amountPence": {
            "type": "integer"
          },
          "method": {
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksBillPaymentMethod"
              }
            ]
          },
          "accountId": {
            "type": "string",
            "format": "uuid"
          },
          "accountName": {
            "type": "string"
          },
          "reference": {
            "type": [
              "string",
              "null"
            ]
          },
          "bankLineId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid",
            "description": "Set when it was matched from a bank line: undo it in Bank."
          },
          "undone": {
            "type": "boolean"
          }
        },
        "description": "A payment made. Undone payments stay listed and no longer count.",
        "required": [
          "id",
          "paidOn",
          "amountPence",
          "method",
          "accountId",
          "accountName",
          "reference",
          "bankLineId",
          "undone"
        ]
      },
      "BooksBillCredit": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "reference": {
            "type": [
              "string",
              "null"
            ]
          },
          "date": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31"
          },
          "amountPence": {
            "type": "integer"
          },
          "reason": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "description": "A posted supplier credit against a bill.",
        "required": [
          "id",
          "reference",
          "date",
          "amountPence",
          "reason"
        ]
      },
      "BooksBillDetail": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "kind": {
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksBillKind"
              }
            ]
          },
          "state": {
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksBillState"
              }
            ]
          },
          "status": {
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksBillStatus"
              }
            ]
          },
          "supplierId": {
            "type": "string",
            "format": "uuid"
          },
          "supplierName": {
            "type": "string"
          },
          "reference": {
            "type": [
              "string",
              "null"
            ],
            "description": "The supplier’s own invoice or credit note number."
          },
          "billDate": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31"
          },
          "dueDate": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31"
          },
          "notes": {
            "type": [
              "string",
              "null"
            ]
          },
          "reason": {
            "type": [
              "string",
              "null"
            ]
          },
          "creditsId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "opening": {
            "type": "boolean",
            "description": "Brought forward with the starting balances: dated before the books start, with no VAT breakdown."
          },
          "receiptId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid",
            "description": "The photo or PDF this came from (GET /books/receipts/{id}/image)."
          },
          "netPence": {
            "type": "integer"
          },
          "vatPence": {
            "type": "integer"
          },
          "grossPence": {
            "type": "integer"
          },
          "paidPence": {
            "type": "integer"
          },
          "creditedPence": {
            "type": "integer"
          },
          "outstandingPence": {
            "type": "integer"
          },
          "overpaidPence": {
            "type": "integer"
          },
          "daysOverdue": {
            "type": "integer"
          },
          "ledgerEntryId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "postedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "lines": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BooksBillLine"
            }
          },
          "payments": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BooksBillPayment"
            }
          },
          "credits": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BooksBillCredit"
            }
          }
        },
        "required": [
          "id",
          "kind",
          "state",
          "status",
          "supplierId",
          "supplierName",
          "reference",
          "billDate",
          "dueDate",
          "notes",
          "reason",
          "creditsId",
          "opening",
          "receiptId",
          "netPence",
          "vatPence",
          "grossPence",
          "paidPence",
          "creditedPence",
          "outstandingPence",
          "overpaidPence",
          "daysOverdue",
          "ledgerEntryId",
          "createdAt",
          "postedAt",
          "lines",
          "payments",
          "credits"
        ]
      },
      "BooksBillProposalLine": {
        "type": "object",
        "properties": {
          "description": {
            "type": "string"
          },
          "accountId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "netPence": {
            "type": "integer"
          },
          "vatCode": {
            "type": "string"
          },
          "vatPence": {
            "type": "integer"
          },
          "checkThis": {
            "type": "boolean",
            "description": "Tolvi AI was barely sure of this line: highlight it for the person to check. It never stops them."
          },
          "checkReason": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "description",
          "accountId",
          "netPence",
          "vatCode",
          "vatPence",
          "checkThis",
          "checkReason"
        ]
      },
      "BooksBillProposalReading": {
        "type": "string",
        "enum": [
          "waiting",
          "queued",
          "reading",
          "done",
          "failed"
        ]
      },
      "BooksBillProposal": {
        "type": "object",
        "properties": {
          "receiptId": {
            "type": "string",
            "format": "uuid"
          },
          "existingBillId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid",
            "description": "A draft already started from this file: open that instead."
          },
          "supplierId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid",
            "description": "The supplier if the name read matches one."
          },
          "supplierName": {
            "type": [
              "string",
              "null"
            ]
          },
          "reference": {
            "type": [
              "string",
              "null"
            ]
          },
          "billDate": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31"
          },
          "dueDate": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31"
          },
          "lines": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BooksBillProposalLine"
            }
          },
          "warnings": {
            "description": "What to check, in plain English.",
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "documentTotalPence": {
            "type": [
              "integer",
              "null"
            ],
            "description": "The total printed on the document, to compare the lines with. Null when it couldn’t be read or isn’t in pounds."
          },
          "linesWarning": {
            "type": [
              "string",
              "null"
            ],
            "description": "Which of the warnings says the lines don’t add up, so it can go once they do."
          },
          "readingStatus": {
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksBillProposalReading"
              }
            ]
          },
          "foreignCurrency": {
            "type": [
              "string",
              "null"
            ],
            "description": "The currency, when the document isn’t in pounds. Bills are in pounds, so no amount is suggested."
          }
        },
        "description": "A bill as Tolvi AI read it from a receipt or bill: a suggestion. Nothing is saved until the person checks it and creates the bill.",
        "required": [
          "receiptId",
          "existingBillId",
          "supplierId",
          "supplierName",
          "reference",
          "billDate",
          "dueDate",
          "lines",
          "warnings",
          "documentTotalPence",
          "linesWarning",
          "readingStatus",
          "foreignCurrency"
        ]
      },
      "BooksUpdateBill": {
        "type": "object",
        "properties": {
          "supplierId": {
            "type": "string",
            "format": "uuid"
          },
          "supplierName": {
            "type": "string",
            "maxLength": 200
          },
          "reference": {
            "type": [
              "string",
              "null"
            ]
          },
          "billDate": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31"
          },
          "dueDate": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-03-31"
          },
          "notes": {
            "type": [
              "string",
              "null"
            ]
          },
          "lines": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BooksBillLineInput"
            }
          }
        }
      },
      "BooksCreditBill": {
        "type": "object",
        "properties": {
          "reason": {
            "type": "string",
            "maxLength": 200
          },
          "reference": {
            "type": [
              "string",
              "null"
            ],
            "description": "The supplier’s credit note number."
          },
          "date": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "amountPence": {
            "type": "integer",
            "minimum": 1,
            "description": "Gross. Left out, everything not credited yet."
          }
        },
        "required": [
          "reason"
        ]
      },
      "BooksVoidBill": {
        "type": "object",
        "properties": {
          "reason": {
            "type": "string",
            "maxLength": 200
          },
          "date": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          }
        },
        "required": [
          "reason"
        ]
      },
      "BooksBillPayMethod": {
        "type": "string",
        "enum": [
          "bank_transfer",
          "card",
          "cash",
          "cheque",
          "other"
        ]
      },
      "BooksPayBill": {
        "type": "object",
        "properties": {
          "paidOn": {
            "type": "string",
            "format": "date",
            "example": "2026-03-31"
          },
          "amountPence": {
            "type": "integer",
            "minimum": 1
          },
          "accountId": {
            "type": "string",
            "format": "uuid",
            "description": "The bank, cash or card account it came from, or the owner’s own account (director’s loan, capital introduced, partner’s current account)."
          },
          "method": {
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksBillPayMethod"
              }
            ]
          },
          "reference": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "paidOn",
          "amountPence",
          "accountId"
        ]
      },
      "BooksGettingStartedKey": {
        "type": "string",
        "enum": [
          "details",
          "bank",
          "opening",
          "invoices",
          "vat",
          "accountant"
        ]
      },
      "BooksGettingStartedStep": {
        "type": "object",
        "properties": {
          "key": {
            "allOf": [
              {
                "$ref": "#/components/schemas/BooksGettingStartedKey"
              }
            ]
          },
          "label": {
            "type": "string"
          },
          "done": {
            "type": "boolean"
          },
          "detail": {
            "type": [
              "string",
              "null"
            ],
            "description": "How it was done, when that needs saying."
          }
        },
        "required": [
          "key",
          "label",
          "done",
          "detail"
        ]
      },
      "BooksGettingStarted": {
        "type": "object",
        "properties": {
          "steps": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BooksGettingStartedStep"
            }
          },
          "doneCount": {
            "type": "integer"
          },
          "complete": {
            "type": "boolean",
            "description": "Every step is done."
          },
          "hidden": {
            "type": "boolean",
            "description": "The owner hid the list from Home."
          },
          "notVatRegistered": {
            "type": "boolean",
            "description": "The business said it isn’t registered for VAT."
          },
          "noOpeningBalances": {
            "type": "boolean",
            "description": "The business said it has nothing to bring forward."
          }
        },
        "description": "The new business checklist, worked out from the business’s own data on every read.",
        "required": [
          "steps",
          "doneCount",
          "complete",
          "hidden",
          "notVatRegistered",
          "noOpeningBalances"
        ]
      },
      "BooksUpdateGettingStarted": {
        "type": "object",
        "properties": {
          "hidden": {
            "type": "boolean",
            "description": "Hide the list from Home, or bring it back."
          },
          "notVatRegistered": {
            "type": "boolean",
            "description": "The business isn’t registered for VAT, so that step is done."
          },
          "noOpeningBalances": {
            "type": "boolean",
            "description": "A brand-new business with nothing to bring forward, so the starting balances step is done."
          }
        },
        "description": "Answers only a person can give. The ticks themselves come from the books."
      },
      "RateLimitScope": {
        "type": "string",
        "enum": [
          "person",
          "firm",
          "client",
          "ip"
        ],
        "description": "On a 429, which limit was hit: `person` (one person's web sessions), `firm` (everyone in the firm signed in to the web app), `client` (this API credential or connected app) or `ip` (this address, before sign-in or on a sign-in endpoint)."
      },
      "ProblemDetails": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "example": "about:blank",
            "description": "A URI for the problem type; about:blank means \"see the status\"."
          },
          "title": {
            "type": "string",
            "example": "Forbidden",
            "description": "The HTTP status phrase."
          },
          "status": {
            "type": "integer",
            "example": 403
          },
          "detail": {
            "type": "string",
            "example": "This needs the Manager role or above"
          },
          "instance": {
            "type": "string",
            "example": "/api/v1/work/assign",
            "description": "The request path."
          },
          "errors": {
            "description": "Every validation message, when there was more than one.",
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "rateLimitScope": {
            "example": "person",
            "description": "On a 429, which limit was hit: `person` (one person's web sessions), `firm` (everyone in the firm signed in to the web app), `client` (this API credential or connected app) or `ip` (this address, before sign-in or on a sign-in endpoint).",
            "allOf": [
              {
                "$ref": "#/components/schemas/RateLimitScope"
              }
            ]
          }
        },
        "description": "An RFC 9457 problem details object (application/problem+json).",
        "required": [
          "type",
          "title",
          "status"
        ]
      }
    },
    "headers": {
      "RateLimit-Limit": {
        "description": "Requests allowed in the current window, by the limit closest to running out.",
        "schema": {
          "type": "integer"
        }
      },
      "RateLimit-Remaining": {
        "description": "Requests left in the current window, by the limit closest to running out.",
        "schema": {
          "type": "integer"
        }
      },
      "RateLimit-Reset": {
        "description": "Seconds until the window resets.",
        "schema": {
          "type": "integer"
        }
      },
      "RateLimit-Policy": {
        "description": "The quota policies that apply, e.g. `600;w=60` (a web session lists its person and firm limits: `600;w=60, 3000;w=60`).",
        "schema": {
          "type": "string"
        }
      }
    }
  }
}
