{
  "components": {
    "headers": {
      "X-API-Version": {
        "description": "Current API version date. Monitor for breaking changes.",
        "schema": {
          "example": "2026-03-18",
          "type": "string"
        }
      },
      "X-Idempotent-Replayed": {
        "description": "Present and set to \"true\" when returning a cached idempotent response",
        "schema": {
          "enum": [
            "true"
          ],
          "type": "string"
        }
      },
      "X-RateLimit-Limit": {
        "description": "Maximum number of requests allowed per window",
        "schema": {
          "example": 100,
          "type": "integer"
        }
      },
      "X-RateLimit-Remaining": {
        "description": "Number of requests remaining in the current window",
        "schema": {
          "example": 87,
          "type": "integer"
        }
      },
      "X-RateLimit-Reset": {
        "description": "Unix timestamp (seconds) when the rate limit window resets",
        "schema": {
          "example": 1742310060,
          "type": "integer"
        }
      }
    },
    "parameters": {
      "ActivityId": {
        "description": "Activity unique identifier",
        "in": "path",
        "name": "activityId",
        "required": true,
        "schema": {
          "type": "string"
        }
      },
      "ClientId": {
        "description": "Client unique identifier",
        "in": "path",
        "name": "clientId",
        "required": true,
        "schema": {
          "type": "string"
        }
      },
      "ContactId": {
        "description": "Contact person unique identifier",
        "in": "path",
        "name": "contactId",
        "required": true,
        "schema": {
          "type": "string"
        }
      },
      "Cursor": {
        "description": "Cursor for cursor-based pagination. Use the `nextCursor` value from\na previous response to fetch the next page. When provided, `offset`\nis ignored. The cursor is a base64url-encoded JSON string.\n",
        "in": "query",
        "name": "cursor",
        "schema": {
          "example": "eyJpc3N1ZURhdGUiOiIyMDI2LTAzLTIwIiwiX19pZCI6ImFiYzEyMyJ9",
          "type": "string"
        }
      },
      "DepositId": {
        "description": "Deposit unique identifier",
        "in": "path",
        "name": "depositId",
        "required": true,
        "schema": {
          "type": "string"
        }
      },
      "ExpenseId": {
        "description": "Expense unique identifier",
        "in": "path",
        "name": "expenseId",
        "required": true,
        "schema": {
          "type": "string"
        }
      },
      "Fields": {
        "description": "Comma-separated list of fields to include in the response.\nThe `id` field is always included. Example: `fields=id,name,total`\n",
        "in": "query",
        "name": "fields",
        "schema": {
          "example": "id,name,total",
          "type": "string"
        }
      },
      "FilterCategory": {
        "description": "Filter expenses by category",
        "in": "query",
        "name": "category",
        "schema": {
          "example": "office_supplies",
          "type": "string"
        }
      },
      "FilterClientId": {
        "description": "Filter invoices or quotes by client ID",
        "in": "query",
        "name": "clientId",
        "schema": {
          "type": "string"
        }
      },
      "FilterIsActive": {
        "description": "Filter products by active status",
        "in": "query",
        "name": "isActive",
        "schema": {
          "example": true,
          "type": "boolean"
        }
      },
      "FilterSeriesId": {
        "description": "Filter invoices or quotes by invoice series ID",
        "in": "query",
        "name": "seriesId",
        "schema": {
          "type": "string"
        }
      },
      "FilterStage": {
        "description": "Filter clients by pipeline stage",
        "in": "query",
        "name": "stage",
        "schema": {
          "enum": [
            "lead",
            "contacted",
            "proposal",
            "active",
            "inactive",
            "lost"
          ],
          "example": "active",
          "type": "string"
        }
      },
      "FilterVendorId": {
        "description": "Filter expenses by vendor ID",
        "in": "query",
        "name": "vendorId",
        "schema": {
          "type": "string"
        }
      },
      "From": {
        "description": "Start date filter in ISO format (YYYY-MM-DD)",
        "in": "query",
        "name": "from",
        "schema": {
          "example": "2026-01-01",
          "format": "date",
          "type": "string"
        }
      },
      "IdempotencyKey": {
        "description": "Unique key to prevent duplicate resource creation from network retries.\nIf the same key is sent within 24 hours, the original response is returned\nwith an X-Idempotent-Replayed: true header. Max 64 characters. UUID v4 recommended.\n",
        "in": "header",
        "name": "Idempotency-Key",
        "required": false,
        "schema": {
          "example": "550e8400-e29b-41d4-a716-446655440000",
          "maxLength": 64,
          "type": "string"
        }
      },
      "InvoiceId": {
        "description": "Invoice unique identifier",
        "in": "path",
        "name": "invoiceId",
        "required": true,
        "schema": {
          "type": "string"
        }
      },
      "Limit": {
        "description": "Number of items to return (default 50, max 100)",
        "in": "query",
        "name": "limit",
        "schema": {
          "default": 50,
          "maximum": 100,
          "minimum": 1,
          "type": "integer"
        }
      },
      "NoteId": {
        "description": "Note unique identifier",
        "in": "path",
        "name": "noteId",
        "required": true,
        "schema": {
          "type": "string"
        }
      },
      "Offset": {
        "description": "Number of items to skip for pagination (max 10000)",
        "in": "query",
        "name": "offset",
        "schema": {
          "default": 0,
          "maximum": 10000,
          "minimum": 0,
          "type": "integer"
        }
      },
      "ProductId": {
        "description": "Product unique identifier",
        "in": "path",
        "name": "productId",
        "required": true,
        "schema": {
          "type": "string"
        }
      },
      "QuoteId": {
        "description": "Quote unique identifier",
        "in": "path",
        "name": "quoteId",
        "required": true,
        "schema": {
          "type": "string"
        }
      },
      "Search": {
        "description": "Full-text search query. Searches across relevant fields per resource type\n(e.g., clientName, documentNumber for invoices; name, email for clients).\nCase-insensitive.\n",
        "in": "query",
        "name": "q",
        "schema": {
          "example": "acme",
          "type": "string"
        }
      },
      "To": {
        "description": "End date filter in ISO format (YYYY-MM-DD)",
        "in": "query",
        "name": "to",
        "schema": {
          "example": "2026-12-31",
          "format": "date",
          "type": "string"
        }
      },
      "VendorId": {
        "description": "Vendor unique identifier",
        "in": "path",
        "name": "vendorId",
        "required": true,
        "schema": {
          "type": "string"
        }
      },
      "WebhookId": {
        "description": "Webhook unique identifier",
        "in": "path",
        "name": "webhookId",
        "required": true,
        "schema": {
          "type": "string"
        }
      }
    },
    "responses": {
      "BadRequest": {
        "content": {
          "application/json": {
            "example": {
              "details": [
                {
                  "code": "invalid_type",
                  "message": "Required",
                  "path": [
                    "clientName"
                  ]
                }
              ],
              "error": "Validation error",
              "meta": {
                "requestId": "550e8400-e29b-41d4-a716-446655440000"
              }
            },
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        },
        "description": "Bad request - invalid parameters or request body"
      },
      "Forbidden": {
        "content": {
          "application/json": {
            "example": {
              "error": "Insufficient permissions",
              "meta": {
                "requestId": "550e8400-e29b-41d4-a716-446655440000"
              }
            },
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        },
        "description": "Insufficient permissions"
      },
      "InternalError": {
        "content": {
          "application/json": {
            "example": {
              "error": "Internal server error",
              "meta": {
                "requestId": "550e8400-e29b-41d4-a716-446655440000"
              }
            },
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        },
        "description": "Internal server error"
      },
      "NotFound": {
        "content": {
          "application/json": {
            "example": {
              "error": "Resource not found",
              "meta": {
                "requestId": "550e8400-e29b-41d4-a716-446655440000"
              }
            },
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        },
        "description": "Resource not found"
      },
      "RateLimited": {
        "content": {
          "application/json": {
            "schema": {
              "properties": {
                "error": {
                  "example": "Rate limit exceeded",
                  "type": "string"
                },
                "message": {
                  "example": "Maximum 100 requests per minute",
                  "type": "string"
                },
                "meta": {
                  "properties": {
                    "requestId": {
                      "type": "string"
                    }
                  },
                  "type": "object"
                },
                "retryAfter": {
                  "description": "Seconds until rate limit resets",
                  "example": 60,
                  "type": "integer"
                }
              },
              "type": "object"
            }
          }
        },
        "description": "Rate limit exceeded (100 requests per minute)"
      },
      "Unauthorized": {
        "content": {
          "application/json": {
            "example": {
              "error": "Invalid or expired API key",
              "meta": {
                "requestId": "550e8400-e29b-41d4-a716-446655440000"
              }
            },
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        },
        "description": "Authentication required or invalid API key"
      }
    },
    "schemas": {
      "Activity": {
        "properties": {
          "createdAt": {
            "format": "date-time",
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "id": {
            "description": "Unique identifier",
            "type": "string"
          },
          "metadata": {
            "additionalProperties": true,
            "type": "object"
          },
          "title": {
            "type": "string"
          },
          "type": {
            "description": "Activity type (manual or system-generated)",
            "type": "string"
          }
        },
        "type": "object"
      },
      "ActivityCreate": {
        "properties": {
          "description": {
            "description": "Detailed description",
            "example": "Discussed budget terms. Awaiting confirmation.",
            "type": "string"
          },
          "metadata": {
            "additionalProperties": true,
            "description": "Free-form additional data",
            "type": "object"
          },
          "title": {
            "description": "Descriptive title for the activity",
            "example": "Follow-up call on Q2 budget",
            "type": "string"
          },
          "type": {
            "$ref": "#/components/schemas/ActivityType"
          }
        },
        "required": [
          "type",
          "title"
        ],
        "type": "object"
      },
      "ActivityType": {
        "description": "Manual activity types. System types (invoice_created, quote_sent, etc.) are auto-generated.",
        "enum": [
          "call",
          "email",
          "meeting",
          "task"
        ],
        "type": "string"
      },
      "Address": {
        "description": "Structured address. Canonical fields are `province` and `zip`.\nThe aliases `state` and `postalCode` are also accepted for backward compatibility.\n",
        "properties": {
          "city": {
            "example": "Madrid",
            "type": "string"
          },
          "country": {
            "example": "ES",
            "type": "string"
          },
          "postalCode": {
            "deprecated": true,
            "description": "Alias for `zip` (backward compatibility)",
            "type": "string"
          },
          "province": {
            "description": "Province or state (canonical field)",
            "example": "Madrid",
            "type": "string"
          },
          "state": {
            "deprecated": true,
            "description": "Alias for `province` (backward compatibility)",
            "type": "string"
          },
          "street": {
            "example": "Calle Gran Via 28",
            "type": "string"
          },
          "zip": {
            "description": "Postal/ZIP code (canonical field)",
            "example": "28013",
            "type": "string"
          }
        },
        "type": "object"
      },
      "BatchResponse": {
        "properties": {
          "data": {
            "items": {
              "properties": {
                "data": {
                  "description": "Created resource (only when success is true)",
                  "type": "object"
                },
                "details": {
                  "description": "Validation error details (only on validation failure)",
                  "items": {
                    "type": "object"
                  },
                  "type": "array"
                },
                "error": {
                  "description": "Error message (only when success is false)",
                  "type": "string"
                },
                "index": {
                  "description": "Index of the item in the original request array",
                  "type": "integer"
                },
                "success": {
                  "type": "boolean"
                }
              },
              "type": "object"
            },
            "type": "array"
          },
          "meta": {
            "properties": {
              "requestId": {
                "type": "string"
              },
              "timestamp": {
                "format": "date-time",
                "type": "string"
              }
            },
            "type": "object"
          },
          "summary": {
            "properties": {
              "failed": {
                "description": "Number of failed items",
                "example": 2,
                "type": "integer"
              },
              "succeeded": {
                "description": "Number of successfully created items",
                "example": 8,
                "type": "integer"
              },
              "total": {
                "description": "Total items in request",
                "example": 10,
                "type": "integer"
              }
            },
            "type": "object"
          }
        },
        "type": "object"
      },
      "BusinessContext": {
        "description": "Comprehensive business context snapshot for AI agents",
        "properties": {
          "data": {
            "properties": {
              "business": {
                "properties": {
                  "country": {
                    "type": "string"
                  },
                  "currency": {
                    "type": "string"
                  },
                  "fiscalZone": {
                    "type": "string"
                  },
                  "language": {
                    "type": "string"
                  },
                  "name": {
                    "type": "string"
                  },
                  "taxId": {
                    "type": "string"
                  }
                },
                "type": "object"
              },
              "currentMonth": {
                "properties": {
                  "expenseCount": {
                    "type": "integer"
                  },
                  "expenses": {
                    "type": "number"
                  },
                  "invoiceCount": {
                    "type": "integer"
                  },
                  "profit": {
                    "type": "number"
                  },
                  "revenue": {
                    "type": "number"
                  }
                },
                "type": "object"
              },
              "defaults": {
                "properties": {
                  "currency": {
                    "type": "string"
                  },
                  "dueDays": {
                    "type": "integer"
                  },
                  "irpfRate": {
                    "type": "number"
                  },
                  "taxRate": {
                    "type": "number"
                  }
                },
                "type": "object"
              },
              "plan": {
                "properties": {
                  "aiMessages": {
                    "properties": {
                      "limit": {
                        "type": "integer"
                      },
                      "used": {
                        "type": "integer"
                      }
                    },
                    "type": "object"
                  },
                  "expenses": {
                    "properties": {
                      "limit": {
                        "type": "integer"
                      },
                      "used": {
                        "type": "integer"
                      }
                    },
                    "type": "object"
                  },
                  "invoices": {
                    "properties": {
                      "limit": {
                        "type": "integer"
                      },
                      "used": {
                        "type": "integer"
                      }
                    },
                    "type": "object"
                  },
                  "name": {
                    "example": "pro",
                    "type": "string"
                  }
                },
                "type": "object"
              },
              "recentActivity": {
                "properties": {
                  "lastExpense": {
                    "nullable": true,
                    "properties": {
                      "amount": {
                        "type": "number"
                      },
                      "date": {
                        "type": "string"
                      },
                      "vendor": {
                        "type": "string"
                      }
                    },
                    "type": "object"
                  },
                  "lastInvoice": {
                    "nullable": true,
                    "properties": {
                      "client": {
                        "type": "string"
                      },
                      "date": {
                        "type": "string"
                      },
                      "number": {
                        "type": "string"
                      }
                    },
                    "type": "object"
                  },
                  "overdueAmount": {
                    "type": "number"
                  },
                  "overdueCount": {
                    "type": "integer"
                  },
                  "unpaidCount": {
                    "type": "integer"
                  }
                },
                "type": "object"
              },
              "series": {
                "items": {
                  "properties": {
                    "current": {
                      "type": "integer"
                    },
                    "id": {
                      "type": "string"
                    },
                    "prefix": {
                      "type": "string"
                    },
                    "year": {
                      "type": "integer"
                    }
                  },
                  "type": "object"
                },
                "type": "array"
              },
              "topClients": {
                "items": {
                  "properties": {
                    "invoiceCount": {
                      "type": "integer"
                    },
                    "name": {
                      "type": "string"
                    },
                    "totalRevenue": {
                      "type": "number"
                    }
                  },
                  "type": "object"
                },
                "type": "array"
              }
            },
            "type": "object"
          },
          "meta": {
            "properties": {
              "requestId": {
                "type": "string"
              },
              "timestamp": {
                "format": "date-time",
                "type": "string"
              }
            },
            "type": "object"
          }
        },
        "type": "object"
      },
      "Channel": {
        "properties": {
          "createdAt": {
            "format": "date-time",
            "type": "string"
          },
          "feedUrl": {
            "nullable": true,
            "type": "string"
          },
          "id": {
            "type": "string"
          },
          "lastSync": {
            "format": "date-time",
            "nullable": true,
            "type": "string"
          },
          "lastSyncEvents": {
            "type": "integer"
          },
          "name": {
            "type": "string"
          },
          "propertyId": {
            "type": "string"
          },
          "status": {
            "type": "string"
          },
          "type": {
            "type": "string"
          },
          "updatedAt": {
            "format": "date-time",
            "type": "string"
          }
        },
        "type": "object"
      },
      "ChannelCreate": {
        "properties": {
          "feedUrl": {
            "description": "iCal feed URL for import",
            "example": "https://www.airbnb.com/calendar/ical/12345.ics",
            "format": "uri",
            "type": "string"
          },
          "name": {
            "description": "Channel name (e.g., \"Airbnb\", \"Booking.com\")",
            "example": "Airbnb",
            "type": "string"
          },
          "propertyId": {
            "description": "ID of the property this channel belongs to",
            "type": "string"
          },
          "status": {
            "$ref": "#/components/schemas/ChannelStatus"
          },
          "type": {
            "default": "ical_import",
            "enum": [
              "ical_import",
              "ical_export",
              "api"
            ],
            "type": "string"
          }
        },
        "required": [
          "propertyId",
          "name"
        ],
        "type": "object"
      },
      "ChannelStatus": {
        "enum": [
          "active",
          "paused",
          "error"
        ],
        "type": "string"
      },
      "Client": {
        "allOf": [
          {
            "properties": {
              "createdAt": {
                "format": "date-time",
                "type": "string"
              },
              "id": {
                "description": "Unique identifier",
                "type": "string"
              },
              "updatedAt": {
                "format": "date-time",
                "type": "string"
              }
            },
            "type": "object"
          },
          {
            "$ref": "#/components/schemas/ClientCreate"
          }
        ]
      },
      "ClientCreate": {
        "properties": {
          "address": {
            "$ref": "#/components/schemas/Address"
          },
          "email": {
            "description": "Contact email",
            "example": "billing@acme.com",
            "format": "email",
            "type": "string"
          },
          "name": {
            "description": "Client name (person or company)",
            "example": "Acme Corp",
            "type": "string"
          },
          "phone": {
            "description": "Phone number",
            "example": "+34 912 345 678",
            "type": "string"
          },
          "taxId": {
            "description": "Tax identification number (NIF/CIF/VAT)",
            "example": "B12345678",
            "type": "string"
          }
        },
        "required": [
          "name"
        ],
        "type": "object"
      },
      "Contact": {
        "allOf": [
          {
            "properties": {
              "createdAt": {
                "format": "date-time",
                "type": "string"
              },
              "id": {
                "description": "Unique identifier",
                "type": "string"
              },
              "updatedAt": {
                "format": "date-time",
                "type": "string"
              }
            },
            "type": "object"
          },
          {
            "$ref": "#/components/schemas/ContactCreate"
          }
        ]
      },
      "ContactCreate": {
        "properties": {
          "email": {
            "description": "Contact email",
            "example": "maria@acme.es",
            "format": "email",
            "type": "string"
          },
          "isPrimary": {
            "default": false,
            "description": "Whether this is the primary contact for the client",
            "type": "boolean"
          },
          "name": {
            "description": "Contact person name",
            "example": "Maria Garcia",
            "type": "string"
          },
          "phone": {
            "description": "Phone number",
            "example": "+34 612 345 678",
            "type": "string"
          },
          "role": {
            "description": "Job title or role",
            "example": "CFO",
            "type": "string"
          }
        },
        "required": [
          "name"
        ],
        "type": "object"
      },
      "Deposit": {
        "allOf": [
          {
            "properties": {
              "createdAt": {
                "format": "date-time",
                "type": "string"
              },
              "id": {
                "description": "Unique identifier",
                "example": "dep_abc123",
                "type": "string"
              },
              "updatedAt": {
                "format": "date-time",
                "type": "string"
              }
            },
            "type": "object"
          },
          {
            "$ref": "#/components/schemas/DepositCreate"
          },
          {
            "properties": {
              "applications": {
                "description": "List of invoice applications for this deposit",
                "items": {
                  "properties": {
                    "amount": {
                      "type": "number"
                    },
                    "appliedAt": {
                      "format": "date",
                      "type": "string"
                    },
                    "invoiceId": {
                      "type": "string"
                    },
                    "invoiceNumber": {
                      "type": "string"
                    }
                  },
                  "type": "object"
                },
                "type": "array"
              },
              "appliedAmount": {
                "description": "Total amount already applied to invoices",
                "example": 250,
                "type": "number"
              },
              "refundedAmount": {
                "description": "Total amount refunded to the client",
                "example": 0,
                "type": "number"
              },
              "remainingBalance": {
                "description": "Remaining balance available for application or refund",
                "example": 500,
                "type": "number"
              },
              "status": {
                "$ref": "#/components/schemas/DepositStatus"
              }
            },
            "type": "object"
          }
        ]
      },
      "DepositCreate": {
        "properties": {
          "amount": {
            "description": "Deposit amount (must be positive)",
            "example": 750,
            "type": "number"
          },
          "clientId": {
            "description": "ID of the client who made the deposit",
            "example": "client_abc123",
            "type": "string"
          },
          "clientName": {
            "description": "Client name (denormalized for display)",
            "example": "Acme Corp",
            "type": "string"
          },
          "currency": {
            "default": "EUR",
            "description": "Currency code (ISO 4217)",
            "example": "EUR",
            "type": "string"
          },
          "description": {
            "description": "Description of the deposit",
            "example": "Prepayment for Q2 project",
            "type": "string"
          },
          "paymentMethod": {
            "description": "Payment method used",
            "example": "bank_transfer",
            "type": "string"
          },
          "paymentReference": {
            "description": "Payment reference or transaction ID",
            "example": "TRF-2026-0042",
            "type": "string"
          },
          "receivedDate": {
            "description": "Date the deposit was received (YYYY-MM-DD)",
            "example": "2026-04-01",
            "format": "date",
            "type": "string"
          }
        },
        "required": [
          "clientId",
          "clientName",
          "amount",
          "description",
          "receivedDate"
        ],
        "type": "object"
      },
      "DepositStatus": {
        "enum": [
          "active",
          "partially_applied",
          "fully_applied",
          "refunded"
        ],
        "type": "string"
      },
      "Error": {
        "properties": {
          "details": {
            "description": "Validation error details (Zod issues). Only present on 400 validation errors.",
            "items": {
              "properties": {
                "code": {
                  "type": "string"
                },
                "message": {
                  "type": "string"
                },
                "path": {
                  "items": {
                    "type": "string"
                  },
                  "type": "array"
                }
              },
              "type": "object"
            },
            "type": "array"
          },
          "error": {
            "description": "Human-readable error message",
            "type": "string"
          },
          "meta": {
            "properties": {
              "requestId": {
                "description": "Unique request identifier for tracing",
                "type": "string"
              }
            },
            "type": "object"
          }
        },
        "required": [
          "error"
        ],
        "type": "object"
      },
      "Expense": {
        "allOf": [
          {
            "properties": {
              "createdAt": {
                "format": "date-time",
                "type": "string"
              },
              "id": {
                "description": "Unique identifier",
                "type": "string"
              },
              "updatedAt": {
                "format": "date-time",
                "type": "string"
              }
            },
            "type": "object"
          },
          {
            "$ref": "#/components/schemas/ExpenseCreate"
          }
        ]
      },
      "ExpenseCreate": {
        "properties": {
          "amount": {
            "description": "Expense amount",
            "example": 45.99,
            "type": "number"
          },
          "category": {
            "description": "Expense category",
            "example": "office",
            "type": "string"
          },
          "date": {
            "description": "Expense date in ISO format",
            "example": "2026-03-09",
            "format": "date",
            "type": "string"
          },
          "description": {
            "description": "Expense description",
            "example": "Office supplies",
            "type": "string"
          },
          "recurring": {
            "$ref": "#/components/schemas/ExpenseRecurringConfig"
          },
          "taxDeductible": {
            "description": "Whether the expense is tax deductible",
            "example": true,
            "type": "boolean"
          },
          "vendor": {
            "description": "Vendor or supplier name",
            "example": "Office Depot",
            "type": "string"
          }
        },
        "required": [
          "description",
          "amount"
        ],
        "type": "object"
      },
      "ExpenseRecurringConfig": {
        "description": "Recurring expense configuration. Set on a template expense to auto-generate copies on schedule.",
        "properties": {
          "enabled": {
            "description": "Whether recurring generation is active",
            "example": true,
            "type": "boolean"
          },
          "endDate": {
            "description": "Stop generating after this date (optional)",
            "example": "2027-03-31",
            "format": "date",
            "type": "string"
          },
          "frequency": {
            "description": "How often to generate a new expense",
            "enum": [
              "weekly",
              "biweekly",
              "monthly",
              "quarterly",
              "yearly"
            ],
            "example": "monthly",
            "type": "string"
          },
          "maxOccurrences": {
            "description": "Maximum number of expenses to generate (optional)",
            "example": 12,
            "minimum": 1,
            "type": "integer"
          },
          "nextDate": {
            "description": "Next scheduled generation date (ISO YYYY-MM-DD)",
            "example": "2026-04-01",
            "format": "date",
            "type": "string"
          },
          "occurrencesGenerated": {
            "description": "Number of expenses generated so far (server-managed, read-only)",
            "example": 0,
            "readOnly": true,
            "type": "integer"
          }
        },
        "required": [
          "enabled",
          "frequency",
          "nextDate"
        ],
        "type": "object"
      },
      "Guest": {
        "properties": {
          "createdAt": {
            "format": "date-time",
            "type": "string"
          },
          "documentNumber": {
            "description": "Redacted for privacy",
            "nullable": true,
            "type": "string"
          },
          "documentType": {
            "enum": [
              "DNI",
              "Passport",
              "NIE"
            ],
            "nullable": true,
            "type": "string"
          },
          "documentVerified": {
            "type": "boolean"
          },
          "guestName": {
            "type": "string"
          },
          "id": {
            "type": "string"
          },
          "nationality": {
            "nullable": true,
            "type": "string"
          },
          "reservationId": {
            "type": "string"
          },
          "signatureCaptured": {
            "type": "boolean"
          },
          "updatedAt": {
            "format": "date-time",
            "type": "string"
          }
        },
        "type": "object"
      },
      "Invoice": {
        "allOf": [
          {
            "properties": {
              "createdAt": {
                "description": "Creation timestamp",
                "format": "date-time",
                "type": "string"
              },
              "id": {
                "description": "Unique identifier",
                "example": "abc123def456",
                "type": "string"
              },
              "updatedAt": {
                "description": "Last update timestamp",
                "format": "date-time",
                "type": "string"
              }
            },
            "type": "object"
          },
          {
            "$ref": "#/components/schemas/InvoiceCreate"
          },
          {
            "properties": {
              "currency": {
                "description": "Currency code",
                "example": "EUR",
                "type": "string"
              },
              "documentNumber": {
                "description": "Auto-generated invoice number",
                "example": "FAC-2026-0042",
                "type": "string"
              },
              "subtotal": {
                "description": "Subtotal before tax",
                "example": 850,
                "type": "number"
              },
              "tax": {
                "description": "Tax amount",
                "example": 178.5,
                "type": "number"
              },
              "total": {
                "description": "Total amount including tax",
                "example": 1028.5,
                "type": "number"
              },
              "verifactuHash": {
                "description": "VeriFactu SHA-256 hash (Spanish tax compliance)",
                "type": "string"
              }
            },
            "type": "object"
          }
        ]
      },
      "InvoiceCreate": {
        "properties": {
          "clientName": {
            "description": "Client name",
            "example": "Acme Corp",
            "type": "string"
          },
          "dueDate": {
            "description": "Due date in ISO format",
            "example": "2026-04-09",
            "format": "date",
            "type": "string"
          },
          "issueDate": {
            "description": "Issue date in ISO format",
            "example": "2026-03-09",
            "format": "date",
            "type": "string"
          },
          "items": {
            "items": {
              "$ref": "#/components/schemas/LineItem"
            },
            "minItems": 1,
            "type": "array"
          },
          "notes": {
            "description": "Additional notes",
            "example": "Payment due within 30 days",
            "type": "string"
          },
          "recurring": {
            "$ref": "#/components/schemas/InvoiceRecurringConfig"
          },
          "status": {
            "$ref": "#/components/schemas/InvoiceStatus"
          },
          "taxRate": {
            "description": "Tax rate percentage",
            "example": 21,
            "maximum": 100,
            "minimum": 0,
            "type": "number"
          }
        },
        "required": [
          "clientName",
          "items"
        ],
        "type": "object"
      },
      "InvoiceRecurringConfig": {
        "description": "Recurring invoice configuration. Set on a template invoice to auto-generate copies on schedule.",
        "properties": {
          "autoSend": {
            "default": false,
            "description": "Automatically send generated invoices to the client",
            "example": false,
            "type": "boolean"
          },
          "enabled": {
            "description": "Whether recurring generation is active",
            "example": true,
            "type": "boolean"
          },
          "endDate": {
            "description": "Stop generating after this date (optional)",
            "example": "2027-03-31",
            "format": "date",
            "type": "string"
          },
          "frequency": {
            "description": "How often to generate a new invoice",
            "enum": [
              "weekly",
              "biweekly",
              "monthly",
              "quarterly",
              "yearly"
            ],
            "example": "monthly",
            "type": "string"
          },
          "lastGeneratedId": {
            "description": "ID of the last auto-generated invoice (server-managed, read-only)",
            "readOnly": true,
            "type": "string"
          },
          "maxOccurrences": {
            "description": "Maximum number of invoices to generate (optional)",
            "example": 12,
            "minimum": 1,
            "type": "integer"
          },
          "nextDate": {
            "description": "Next scheduled generation date (ISO YYYY-MM-DD)",
            "example": "2026-04-01",
            "format": "date",
            "type": "string"
          },
          "occurrencesGenerated": {
            "description": "Number of invoices generated so far (server-managed, read-only)",
            "example": 0,
            "readOnly": true,
            "type": "integer"
          }
        },
        "required": [
          "enabled",
          "frequency",
          "nextDate"
        ],
        "type": "object"
      },
      "InvoiceStatus": {
        "enum": [
          "draft",
          "sent",
          "partial",
          "paid",
          "overdue",
          "cancelled"
        ],
        "type": "string"
      },
      "LineItem": {
        "properties": {
          "description": {
            "description": "Item description",
            "example": "Web development services",
            "type": "string"
          },
          "quantity": {
            "description": "Quantity",
            "example": 10,
            "type": "number"
          },
          "unitPrice": {
            "description": "Price per unit",
            "example": 85,
            "type": "number"
          }
        },
        "required": [
          "description",
          "quantity",
          "unitPrice"
        ],
        "type": "object"
      },
      "MonthlySummary": {
        "properties": {
          "data": {
            "properties": {
              "byCategory": {
                "additionalProperties": {
                  "type": "number"
                },
                "description": "Expense totals grouped by category",
                "type": "object"
              },
              "expenses": {
                "properties": {
                  "deductible": {
                    "type": "number"
                  },
                  "tax": {
                    "type": "number"
                  },
                  "total": {
                    "type": "number"
                  }
                },
                "type": "object"
              },
              "invoices": {
                "properties": {
                  "created": {
                    "type": "integer"
                  },
                  "overdue": {
                    "type": "integer"
                  },
                  "paid": {
                    "type": "integer"
                  },
                  "sent": {
                    "type": "integer"
                  }
                },
                "type": "object"
              },
              "period": {
                "example": "2026-03",
                "type": "string"
              },
              "profit": {
                "properties": {
                  "gross": {
                    "type": "number"
                  },
                  "net": {
                    "type": "number"
                  }
                },
                "type": "object"
              },
              "revenue": {
                "properties": {
                  "irpf": {
                    "type": "number"
                  },
                  "tax": {
                    "type": "number"
                  },
                  "taxBase": {
                    "type": "number"
                  },
                  "total": {
                    "type": "number"
                  }
                },
                "type": "object"
              },
              "taxLiability": {
                "properties": {
                  "estimatedModel303": {
                    "type": "number"
                  },
                  "irpfRetained": {
                    "type": "number"
                  },
                  "vatPayable": {
                    "description": "Net VAT payable (output - input)",
                    "type": "number"
                  }
                },
                "type": "object"
              },
              "topClients": {
                "items": {
                  "properties": {
                    "invoiceCount": {
                      "type": "integer"
                    },
                    "name": {
                      "type": "string"
                    },
                    "totalRevenue": {
                      "type": "number"
                    }
                  },
                  "type": "object"
                },
                "type": "array"
              }
            },
            "type": "object"
          },
          "meta": {
            "properties": {
              "requestId": {
                "type": "string"
              },
              "timestamp": {
                "format": "date-time",
                "type": "string"
              }
            },
            "type": "object"
          }
        },
        "type": "object"
      },
      "Note": {
        "allOf": [
          {
            "properties": {
              "createdAt": {
                "format": "date-time",
                "type": "string"
              },
              "id": {
                "description": "Unique identifier",
                "type": "string"
              },
              "updatedAt": {
                "format": "date-time",
                "type": "string"
              }
            },
            "type": "object"
          },
          {
            "$ref": "#/components/schemas/NoteCreate"
          }
        ]
      },
      "NoteCreate": {
        "properties": {
          "content": {
            "description": "Note content",
            "example": "Client interested in Business plan. Follow up in April.",
            "type": "string"
          }
        },
        "required": [
          "content"
        ],
        "type": "object"
      },
      "PaginatedResponse": {
        "properties": {
          "data": {
            "items": {},
            "type": "array"
          },
          "limit": {
            "description": "Number of items per page",
            "type": "integer"
          },
          "nextCursor": {
            "description": "Cursor for fetching the next page of results. Only present when there\nare more results available. Pass this value as the `cursor` query parameter\nin the next request. Base64url-encoded.\n",
            "example": "eyJpc3N1ZURhdGUiOiIyMDI2LTAzLTIwIiwiX19pZCI6ImFiYzEyMyJ9",
            "type": "string"
          },
          "offset": {
            "description": "Current offset",
            "type": "integer"
          },
          "total": {
            "description": "Total number of items matching the query",
            "type": "integer"
          }
        },
        "type": "object"
      },
      "Product": {
        "allOf": [
          {
            "properties": {
              "createdAt": {
                "format": "date-time",
                "type": "string"
              },
              "id": {
                "description": "Unique identifier",
                "type": "string"
              },
              "updatedAt": {
                "format": "date-time",
                "type": "string"
              }
            },
            "type": "object"
          },
          {
            "$ref": "#/components/schemas/ProductCreate"
          }
        ]
      },
      "ProductCreate": {
        "properties": {
          "description": {
            "description": "Product description",
            "example": "One hour of strategic consulting",
            "type": "string"
          },
          "name": {
            "description": "Product or service name",
            "example": "Consulting Hour",
            "type": "string"
          },
          "taxRate": {
            "description": "Default tax rate percentage",
            "example": 21,
            "maximum": 100,
            "minimum": 0,
            "type": "number"
          },
          "unitPrice": {
            "description": "Unit price",
            "example": 120,
            "type": "number"
          }
        },
        "required": [
          "name",
          "unitPrice"
        ],
        "type": "object"
      },
      "Property": {
        "properties": {
          "address": {
            "type": "string"
          },
          "commissionRate": {
            "type": "number"
          },
          "createdAt": {
            "format": "date-time",
            "type": "string"
          },
          "id": {
            "type": "string"
          },
          "licenseNumber": {
            "nullable": true,
            "type": "string"
          },
          "maxGuests": {
            "type": "integer"
          },
          "name": {
            "type": "string"
          },
          "ownerEmail": {
            "nullable": true,
            "type": "string"
          },
          "ownerName": {
            "type": "string"
          },
          "status": {
            "$ref": "#/components/schemas/PropertyStatus"
          },
          "type": {
            "type": "string"
          },
          "updatedAt": {
            "format": "date-time",
            "type": "string"
          }
        },
        "type": "object"
      },
      "PropertyCreate": {
        "properties": {
          "address": {
            "example": "Calle Sol 12, Santa Cruz",
            "type": "string"
          },
          "commissionRate": {
            "description": "Commission percentage (0-100)",
            "example": 15,
            "maximum": 100,
            "minimum": 0,
            "type": "number"
          },
          "licenseNumber": {
            "description": "Tourism license number",
            "example": "VV-38-001234",
            "type": "string"
          },
          "maxGuests": {
            "example": 6,
            "minimum": 1,
            "type": "integer"
          },
          "name": {
            "description": "Property name",
            "example": "Sunset Villa",
            "type": "string"
          },
          "ownerEmail": {
            "format": "email",
            "type": "string"
          },
          "ownerName": {
            "example": "Carlos Martinez",
            "type": "string"
          },
          "status": {
            "$ref": "#/components/schemas/PropertyStatus"
          },
          "type": {
            "enum": [
              "Apartment",
              "Villa",
              "Studio",
              "House",
              "Room"
            ],
            "example": "Villa",
            "type": "string"
          }
        },
        "required": [
          "name"
        ],
        "type": "object"
      },
      "PropertyStatus": {
        "enum": [
          "Active",
          "Maintenance",
          "Inactive"
        ],
        "type": "string"
      },
      "QuarterlySummary": {
        "properties": {
          "data": {
            "properties": {
              "modelo130": {
                "description": "Pre-filled Modelo 130 (quarterly income payment) figures",
                "properties": {
                  "gastos": {
                    "description": "Total deductible expenses",
                    "type": "number"
                  },
                  "ingresos": {
                    "description": "Total income (tax base)",
                    "type": "number"
                  },
                  "pagoFraccionado": {
                    "description": "Estimated quarterly payment (20% of net income)",
                    "type": "number"
                  },
                  "rendimientoNeto": {
                    "description": "Net income (ingresos - gastos)",
                    "type": "number"
                  }
                },
                "type": "object"
              },
              "modelo303": {
                "description": "Pre-filled Modelo 303 (VAT return) figures",
                "properties": {
                  "baseDeducible": {
                    "description": "Deductible expense base",
                    "type": "number"
                  },
                  "baseImponible": {
                    "description": "Total tax base",
                    "type": "number"
                  },
                  "cuotaDeducible": {
                    "description": "Input VAT (paid on deductible expenses)",
                    "type": "number"
                  },
                  "cuotaRepercutida": {
                    "description": "Output VAT (charged to clients)",
                    "type": "number"
                  },
                  "resultado": {
                    "description": "Net VAT (output - input)",
                    "type": "number"
                  }
                },
                "type": "object"
              },
              "months": {
                "example": [
                  "2026-01",
                  "2026-02",
                  "2026-03"
                ],
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              "period": {
                "example": "2026-Q1",
                "type": "string"
              },
              "summary": {
                "properties": {
                  "clientCount": {
                    "type": "integer"
                  },
                  "invoiceCount": {
                    "type": "integer"
                  },
                  "totalExpenses": {
                    "type": "number"
                  },
                  "totalRevenue": {
                    "type": "number"
                  }
                },
                "type": "object"
              }
            },
            "type": "object"
          },
          "meta": {
            "properties": {
              "requestId": {
                "type": "string"
              },
              "timestamp": {
                "format": "date-time",
                "type": "string"
              }
            },
            "type": "object"
          }
        },
        "type": "object"
      },
      "Quote": {
        "allOf": [
          {
            "properties": {
              "createdAt": {
                "format": "date-time",
                "type": "string"
              },
              "id": {
                "description": "Unique identifier",
                "type": "string"
              },
              "updatedAt": {
                "format": "date-time",
                "type": "string"
              }
            },
            "type": "object"
          },
          {
            "$ref": "#/components/schemas/QuoteCreate"
          },
          {
            "properties": {
              "documentNumber": {
                "description": "Auto-generated quote number",
                "example": "PRE-2026-0015",
                "type": "string"
              },
              "subtotal": {
                "description": "Subtotal before tax",
                "type": "number"
              },
              "tax": {
                "description": "Tax amount",
                "type": "number"
              },
              "total": {
                "description": "Total amount including tax",
                "type": "number"
              }
            },
            "type": "object"
          }
        ]
      },
      "QuoteCreate": {
        "properties": {
          "clientName": {
            "description": "Client name",
            "example": "Acme Corp",
            "type": "string"
          },
          "items": {
            "items": {
              "$ref": "#/components/schemas/LineItem"
            },
            "minItems": 1,
            "type": "array"
          },
          "notes": {
            "description": "Additional notes",
            "example": "Valid for 30 days",
            "type": "string"
          },
          "status": {
            "$ref": "#/components/schemas/QuoteStatus"
          },
          "validUntil": {
            "description": "Quote expiration date",
            "example": "2026-04-09",
            "format": "date",
            "type": "string"
          }
        },
        "required": [
          "clientName",
          "items"
        ],
        "type": "object"
      },
      "QuoteStatus": {
        "enum": [
          "draft",
          "sent",
          "accepted",
          "rejected",
          "expired"
        ],
        "type": "string"
      },
      "ReceiptQueueItem": {
        "description": "A receipt or invoice queued for OCR processing from an inbound email.",
        "properties": {
          "error": {
            "description": "Error message when status=failed",
            "nullable": true,
            "type": "string"
          },
          "expenseId": {
            "description": "Created expense ID after OCR completes (available when status=done)",
            "nullable": true,
            "type": "string"
          },
          "id": {
            "type": "string"
          },
          "mimeType": {
            "type": "string"
          },
          "originalFilename": {
            "type": "string"
          },
          "receivedAt": {
            "format": "date-time",
            "type": "string"
          },
          "sourceEmail": {
            "description": "Email address that sent the attachment",
            "type": "string"
          },
          "status": {
            "enum": [
              "queued",
              "processing",
              "done",
              "failed"
            ],
            "type": "string"
          },
          "storagePath": {
            "description": "Firebase Storage path after upload (available when status=done)",
            "nullable": true,
            "type": "string"
          },
          "subject": {
            "type": "string"
          },
          "updatedAt": {
            "format": "date-time",
            "type": "string"
          },
          "workspaceUid": {
            "type": "string"
          }
        },
        "type": "object"
      },
      "ResendInboundPayload": {
        "description": "Payload sent by Resend for inbound email routing.",
        "properties": {
          "attachments": {
            "items": {
              "properties": {
                "content": {
                  "description": "Base64-encoded file content",
                  "type": "string"
                },
                "content_type": {
                  "description": "MIME type of the attachment",
                  "example": "application/pdf",
                  "type": "string"
                },
                "filename": {
                  "description": "Original filename of the attachment",
                  "example": "invoice.pdf",
                  "type": "string"
                }
              },
              "type": "object"
            },
            "type": "array"
          },
          "from": {
            "description": "Sender email address",
            "example": "vendor@example.com",
            "type": "string"
          },
          "html": {
            "description": "HTML body",
            "type": "string"
          },
          "subject": {
            "description": "Email subject line",
            "example": "Invoice #1234 from Acme Corp",
            "type": "string"
          },
          "text": {
            "description": "Plain text body",
            "type": "string"
          },
          "to": {
            "description": "Recipient email addresses. Should include receipts@<slug>.frihet.io",
            "example": [
              "receipts@myworkspace.frihet.io"
            ],
            "items": {
              "type": "string"
            },
            "type": "array"
          }
        },
        "type": "object"
      },
      "Reservation": {
        "properties": {
          "amount": {
            "type": "number"
          },
          "channel": {
            "type": "string"
          },
          "checkIn": {
            "format": "date-time",
            "type": "string"
          },
          "checkOut": {
            "format": "date-time",
            "type": "string"
          },
          "complianceStatus": {
            "type": "string"
          },
          "confirmationCode": {
            "nullable": true,
            "type": "string"
          },
          "createdAt": {
            "format": "date-time",
            "type": "string"
          },
          "guestEmail": {
            "nullable": true,
            "type": "string"
          },
          "guestName": {
            "type": "string"
          },
          "id": {
            "type": "string"
          },
          "nights": {
            "type": "integer"
          },
          "notes": {
            "nullable": true,
            "type": "string"
          },
          "propertyId": {
            "type": "string"
          },
          "status": {
            "$ref": "#/components/schemas/ReservationStatus"
          },
          "updatedAt": {
            "format": "date-time",
            "type": "string"
          }
        },
        "type": "object"
      },
      "ReservationCreate": {
        "properties": {
          "amount": {
            "description": "Total amount in EUR",
            "example": 450,
            "type": "number"
          },
          "channel": {
            "enum": [
              "Direct",
              "Airbnb",
              "Booking.com",
              "Vrbo"
            ],
            "example": "Airbnb",
            "type": "string"
          },
          "checkIn": {
            "description": "Check-in date (ISO 8601)",
            "example": "2026-05-01",
            "format": "date",
            "type": "string"
          },
          "checkOut": {
            "description": "Check-out date (ISO 8601)",
            "example": "2026-05-05",
            "format": "date",
            "type": "string"
          },
          "complianceStatus": {
            "enum": [
              "Not Started",
              "In Progress",
              "Completed",
              "Failed"
            ],
            "type": "string"
          },
          "confirmationCode": {
            "example": "HM4X7K",
            "type": "string"
          },
          "guestEmail": {
            "example": "maria@example.com",
            "format": "email",
            "type": "string"
          },
          "guestName": {
            "description": "Guest full name",
            "example": "Maria Lopez",
            "type": "string"
          },
          "nights": {
            "minimum": 0,
            "type": "integer"
          },
          "notes": {
            "type": "string"
          },
          "propertyId": {
            "description": "ID of the property",
            "type": "string"
          },
          "status": {
            "$ref": "#/components/schemas/ReservationStatus"
          }
        },
        "required": [
          "guestName",
          "propertyId",
          "checkIn",
          "checkOut"
        ],
        "type": "object"
      },
      "ReservationStatus": {
        "enum": [
          "Pending",
          "Confirmed",
          "Checked In",
          "Checked Out",
          "Cancelled"
        ],
        "type": "string"
      },
      "SendEmailRequest": {
        "properties": {
          "customMessage": {
            "description": "Optional custom message to include in the email",
            "example": "Please find attached your invoice.",
            "type": "string"
          },
          "locale": {
            "default": "es",
            "description": "Email language",
            "enum": [
              "es",
              "en"
            ],
            "type": "string"
          },
          "recipientEmail": {
            "description": "Recipient email address",
            "example": "client@example.com",
            "format": "email",
            "type": "string"
          },
          "recipientName": {
            "description": "Recipient name",
            "example": "John Doe",
            "type": "string"
          }
        },
        "required": [
          "recipientEmail"
        ],
        "type": "object"
      },
      "Summary": {
        "properties": {
          "counts": {
            "properties": {
              "clients": {
                "example": 23,
                "type": "integer"
              },
              "expenses": {
                "example": 87,
                "type": "integer"
              },
              "invoices": {
                "example": 42,
                "type": "integer"
              },
              "products": {
                "example": 12,
                "type": "integer"
              },
              "quotes": {
                "example": 15,
                "type": "integer"
              }
            },
            "type": "object"
          },
          "expenses": {
            "properties": {
              "total": {
                "description": "Total expenses",
                "example": 8200,
                "type": "number"
              }
            },
            "type": "object"
          },
          "invoicesByStatus": {
            "additionalProperties": {
              "type": "integer"
            },
            "example": {
              "draft": 3,
              "overdue": 3,
              "paid": 28,
              "sent": 8
            },
            "type": "object"
          },
          "overdue": {
            "properties": {
              "amount": {
                "example": 2000,
                "type": "number"
              },
              "count": {
                "example": 3,
                "type": "integer"
              }
            },
            "type": "object"
          },
          "period": {
            "properties": {
              "from": {
                "format": "date",
                "nullable": true,
                "type": "string"
              },
              "to": {
                "format": "date",
                "nullable": true,
                "type": "string"
              }
            },
            "type": "object"
          },
          "profit": {
            "description": "Net profit (paid revenue minus expenses)",
            "example": 10300,
            "type": "number"
          },
          "revenue": {
            "properties": {
              "invoiced": {
                "description": "Total invoiced amount",
                "example": 25000,
                "type": "number"
              },
              "overdue": {
                "description": "Total overdue amount",
                "example": 2000,
                "type": "number"
              },
              "paid": {
                "description": "Total paid amount",
                "example": 18500,
                "type": "number"
              },
              "pending": {
                "description": "Total pending (sent but unpaid)",
                "example": 4500,
                "type": "number"
              }
            },
            "type": "object"
          }
        },
        "type": "object"
      },
      "Vendor": {
        "allOf": [
          {
            "properties": {
              "createdAt": {
                "format": "date-time",
                "type": "string"
              },
              "id": {
                "description": "Unique identifier",
                "type": "string"
              },
              "updatedAt": {
                "format": "date-time",
                "type": "string"
              }
            },
            "type": "object"
          },
          {
            "$ref": "#/components/schemas/VendorCreate"
          }
        ]
      },
      "VendorCreate": {
        "properties": {
          "address": {
            "$ref": "#/components/schemas/Address"
          },
          "email": {
            "description": "Contact email",
            "example": "billing@officedepot.com",
            "format": "email",
            "type": "string"
          },
          "name": {
            "description": "Vendor name (person or company)",
            "example": "Office Depot",
            "type": "string"
          },
          "phone": {
            "description": "Phone number",
            "example": "+34 912 345 678",
            "type": "string"
          },
          "taxId": {
            "description": "Tax identification number (NIF/CIF/VAT)",
            "example": "B87654321",
            "type": "string"
          }
        },
        "required": [
          "name"
        ],
        "type": "object"
      },
      "Webhook": {
        "allOf": [
          {
            "properties": {
              "createdAt": {
                "format": "date-time",
                "type": "string"
              },
              "id": {
                "description": "Unique identifier",
                "type": "string"
              },
              "updatedAt": {
                "format": "date-time",
                "type": "string"
              },
              "userId": {
                "type": "string"
              }
            },
            "type": "object"
          },
          {
            "$ref": "#/components/schemas/WebhookCreate"
          }
        ]
      },
      "WebhookCreate": {
        "properties": {
          "events": {
            "description": "List of event types to subscribe to",
            "example": [
              "invoice.created",
              "invoice.paid",
              "expense.created"
            ],
            "items": {
              "maxLength": 100,
              "type": "string"
            },
            "minItems": 1,
            "type": "array"
          },
          "metadata": {
            "additionalProperties": true,
            "description": "Arbitrary metadata to attach to the webhook",
            "type": "object"
          },
          "name": {
            "description": "Webhook name",
            "example": "Invoice notifications",
            "maxLength": 200,
            "type": "string"
          },
          "secret": {
            "description": "HMAC secret for verifying webhook signatures",
            "maxLength": 500,
            "type": "string"
          },
          "status": {
            "default": "active",
            "enum": [
              "active",
              "inactive"
            ],
            "type": "string"
          },
          "url": {
            "description": "Endpoint URL to receive webhook events",
            "example": "https://example.com/webhooks/frihet",
            "format": "uri",
            "maxLength": 2000,
            "type": "string"
          }
        },
        "required": [
          "name",
          "url",
          "events"
        ],
        "type": "object"
      },
      "WebhookUpdate": {
        "properties": {
          "events": {
            "items": {
              "type": "string"
            },
            "minItems": 1,
            "type": "array"
          },
          "metadata": {
            "additionalProperties": true,
            "type": "object"
          },
          "name": {
            "maxLength": 200,
            "type": "string"
          },
          "secret": {
            "maxLength": 500,
            "type": "string"
          },
          "status": {
            "enum": [
              "active",
              "inactive",
              "paused"
            ],
            "type": "string"
          },
          "url": {
            "format": "uri",
            "maxLength": 2000,
            "type": "string"
          }
        },
        "type": "object"
      }
    },
    "securitySchemes": {
      "ApiKeyAuth": {
        "description": "API key for authentication. Keys start with `fri_` prefix.\nGenerate keys from Settings > API Keys in the Frihet app.\n",
        "in": "header",
        "name": "X-API-Key",
        "type": "apiKey"
      }
    }
  },
  "info": {
    "contact": {
      "email": "ayuda@frihet.io",
      "name": "Frihet Support",
      "url": "https://docs.frihet.io"
    },
    "description": "REST API for Frihet ERP. Full documentation at https://docs.frihet.io/developers/api-rest",
    "license": {
      "name": "MIT",
      "url": "https://opensource.org/licenses/MIT"
    },
    "title": "Frihet API",
    "version": "2026-03-18",
    "x-logo": {
      "url": "https://www.frihet.io/logo.png"
    }
  },
  "openapi": "3.1.0",
  "paths": {
    "/v1/channels": {
      "get": {
        "description": "Retrieve channel connections (iCal feeds) for calendar sync.",
        "operationId": "listChannels",
        "parameters": [
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "$ref": "#/components/parameters/Offset"
          },
          {
            "$ref": "#/components/parameters/Cursor"
          },
          {
            "$ref": "#/components/parameters/Fields"
          },
          {
            "in": "query",
            "name": "status",
            "schema": {
              "$ref": "#/components/schemas/ChannelStatus"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/PaginatedResponse"
                    },
                    {
                      "properties": {
                        "data": {
                          "items": {
                            "$ref": "#/components/schemas/Channel"
                          },
                          "type": "array"
                        }
                      },
                      "type": "object"
                    }
                  ]
                }
              }
            },
            "description": "A paginated list of channels"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        },
        "summary": "List channels",
        "tags": [
          "Channels"
        ]
      },
      "post": {
        "operationId": "createChannel",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ChannelCreate"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Channel"
                }
              }
            },
            "description": "Channel created"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        },
        "summary": "Create a channel (add iCal feed)",
        "tags": [
          "Channels"
        ]
      }
    },
    "/v1/channels/{channelId}": {
      "delete": {
        "operationId": "deleteChannel",
        "parameters": [
          {
            "in": "path",
            "name": "channelId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Channel deleted"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        },
        "summary": "Remove a channel",
        "tags": [
          "Channels"
        ]
      }
    },
    "/v1/channels/{channelId}/sync": {
      "post": {
        "description": "Triggers a sync of the iCal feed for this channel.",
        "operationId": "syncChannel",
        "parameters": [
          {
            "in": "path",
            "name": "channelId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "data": {
                      "properties": {
                        "channelId": {
                          "type": "string"
                        },
                        "message": {
                          "type": "string"
                        },
                        "success": {
                          "type": "boolean"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Sync triggered"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        },
        "summary": "Trigger channel sync",
        "tags": [
          "Channels"
        ]
      }
    },
    "/v1/clients": {
      "get": {
        "description": "Retrieve a paginated list of clients with optional search.",
        "operationId": "listClients",
        "parameters": [
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "$ref": "#/components/parameters/Offset"
          },
          {
            "$ref": "#/components/parameters/Cursor"
          },
          {
            "$ref": "#/components/parameters/From"
          },
          {
            "$ref": "#/components/parameters/To"
          },
          {
            "$ref": "#/components/parameters/Search"
          },
          {
            "$ref": "#/components/parameters/Fields"
          },
          {
            "$ref": "#/components/parameters/FilterStage"
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/PaginatedResponse"
                    },
                    {
                      "properties": {
                        "data": {
                          "items": {
                            "$ref": "#/components/schemas/Client"
                          },
                          "type": "array"
                        }
                      },
                      "type": "object"
                    }
                  ]
                }
              }
            },
            "description": "A paginated list of clients"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        },
        "summary": "List clients",
        "tags": [
          "Clients"
        ]
      },
      "post": {
        "description": "Add a new client to your database.",
        "operationId": "createClient",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ClientCreate"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Client"
                }
              }
            },
            "description": "Client created"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        },
        "summary": "Create a client",
        "tags": [
          "Clients"
        ]
      }
    },
    "/v1/clients/{clientId}": {
      "delete": {
        "description": "Permanently delete a client from your database.",
        "operationId": "deleteClient",
        "parameters": [
          {
            "$ref": "#/components/parameters/ClientId"
          }
        ],
        "responses": {
          "204": {
            "description": "Client deleted"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        },
        "summary": "Delete a client",
        "tags": [
          "Clients"
        ]
      },
      "get": {
        "description": "Retrieve a single client by ID.",
        "operationId": "getClient",
        "parameters": [
          {
            "$ref": "#/components/parameters/ClientId"
          },
          {
            "$ref": "#/components/parameters/Fields"
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Client"
                }
              }
            },
            "description": "Client details"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        },
        "summary": "Get a client",
        "tags": [
          "Clients"
        ]
      },
      "patch": {
        "description": "Update only the provided fields on an existing client.",
        "operationId": "patchClient",
        "parameters": [
          {
            "$ref": "#/components/parameters/ClientId"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ClientCreate"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Client"
                }
              }
            },
            "description": "Client updated"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        },
        "summary": "Partial update a client",
        "tags": [
          "Clients"
        ]
      },
      "put": {
        "description": "Replace all fields on an existing client.",
        "operationId": "updateClient",
        "parameters": [
          {
            "$ref": "#/components/parameters/ClientId"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ClientCreate"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Client"
                }
              }
            },
            "description": "Client updated"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        },
        "summary": "Full update a client",
        "tags": [
          "Clients"
        ]
      }
    },
    "/v1/clients/{clientId}/activities": {
      "get": {
        "description": "Retrieve the activity timeline for a client.",
        "operationId": "listClientActivities",
        "parameters": [
          {
            "$ref": "#/components/parameters/ClientId"
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "data": {
                      "items": {
                        "$ref": "#/components/schemas/Activity"
                      },
                      "type": "array"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "List of activities"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        },
        "summary": "List client activities",
        "tags": [
          "Activities"
        ]
      },
      "post": {
        "description": "Add a manual activity to the client timeline. Activities are immutable once created.",
        "operationId": "createClientActivity",
        "parameters": [
          {
            "$ref": "#/components/parameters/ClientId"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ActivityCreate"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Activity"
                }
              }
            },
            "description": "Activity created"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        },
        "summary": "Create a client activity",
        "tags": [
          "Activities"
        ]
      }
    },
    "/v1/clients/{clientId}/activities/{activityId}": {
      "get": {
        "description": "Retrieve a single activity by ID.",
        "operationId": "getClientActivity",
        "parameters": [
          {
            "$ref": "#/components/parameters/ClientId"
          },
          {
            "$ref": "#/components/parameters/ActivityId"
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Activity"
                }
              }
            },
            "description": "Activity details"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        },
        "summary": "Get a client activity",
        "tags": [
          "Activities"
        ]
      }
    },
    "/v1/clients/{clientId}/contacts": {
      "get": {
        "description": "Retrieve all contact persons for a client.",
        "operationId": "listClientContacts",
        "parameters": [
          {
            "$ref": "#/components/parameters/ClientId"
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "data": {
                      "items": {
                        "$ref": "#/components/schemas/Contact"
                      },
                      "type": "array"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "List of contacts"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        },
        "summary": "List client contacts",
        "tags": [
          "Contacts"
        ]
      },
      "post": {
        "description": "Add a new contact person to a client.",
        "operationId": "createClientContact",
        "parameters": [
          {
            "$ref": "#/components/parameters/ClientId"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ContactCreate"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Contact"
                }
              }
            },
            "description": "Contact created"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        },
        "summary": "Create a client contact",
        "tags": [
          "Contacts"
        ]
      }
    },
    "/v1/clients/{clientId}/contacts/{contactId}": {
      "delete": {
        "description": "Permanently delete a contact person from a client.",
        "operationId": "deleteClientContact",
        "parameters": [
          {
            "$ref": "#/components/parameters/ClientId"
          },
          {
            "$ref": "#/components/parameters/ContactId"
          }
        ],
        "responses": {
          "204": {
            "description": "Contact deleted"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        },
        "summary": "Delete a client contact",
        "tags": [
          "Contacts"
        ]
      },
      "get": {
        "description": "Retrieve a single contact person by ID.",
        "operationId": "getClientContact",
        "parameters": [
          {
            "$ref": "#/components/parameters/ClientId"
          },
          {
            "$ref": "#/components/parameters/ContactId"
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Contact"
                }
              }
            },
            "description": "Contact details"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        },
        "summary": "Get a client contact",
        "tags": [
          "Contacts"
        ]
      },
      "patch": {
        "description": "Update fields on an existing contact person.",
        "operationId": "updateClientContact",
        "parameters": [
          {
            "$ref": "#/components/parameters/ClientId"
          },
          {
            "$ref": "#/components/parameters/ContactId"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ContactCreate"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Contact"
                }
              }
            },
            "description": "Contact updated"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        },
        "summary": "Update a client contact",
        "tags": [
          "Contacts"
        ]
      }
    },
    "/v1/clients/{clientId}/notes": {
      "get": {
        "description": "Retrieve all notes for a client.",
        "operationId": "listClientNotes",
        "parameters": [
          {
            "$ref": "#/components/parameters/ClientId"
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "data": {
                      "items": {
                        "$ref": "#/components/schemas/Note"
                      },
                      "type": "array"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "List of notes"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        },
        "summary": "List client notes",
        "tags": [
          "Notes"
        ]
      },
      "post": {
        "description": "Add a new note to a client.",
        "operationId": "createClientNote",
        "parameters": [
          {
            "$ref": "#/components/parameters/ClientId"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/NoteCreate"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Note"
                }
              }
            },
            "description": "Note created"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        },
        "summary": "Create a client note",
        "tags": [
          "Notes"
        ]
      }
    },
    "/v1/clients/{clientId}/notes/{noteId}": {
      "delete": {
        "description": "Permanently delete a note from a client.",
        "operationId": "deleteClientNote",
        "parameters": [
          {
            "$ref": "#/components/parameters/ClientId"
          },
          {
            "$ref": "#/components/parameters/NoteId"
          }
        ],
        "responses": {
          "204": {
            "description": "Note deleted"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        },
        "summary": "Delete a client note",
        "tags": [
          "Notes"
        ]
      },
      "get": {
        "description": "Retrieve a single note by ID.",
        "operationId": "getClientNote",
        "parameters": [
          {
            "$ref": "#/components/parameters/ClientId"
          },
          {
            "$ref": "#/components/parameters/NoteId"
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Note"
                }
              }
            },
            "description": "Note details"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        },
        "summary": "Get a client note",
        "tags": [
          "Notes"
        ]
      },
      "patch": {
        "description": "Update the content of an existing note.",
        "operationId": "updateClientNote",
        "parameters": [
          {
            "$ref": "#/components/parameters/ClientId"
          },
          {
            "$ref": "#/components/parameters/NoteId"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/NoteCreate"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Note"
                }
              }
            },
            "description": "Note updated"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        },
        "summary": "Update a client note",
        "tags": [
          "Notes"
        ]
      }
    },
    "/v1/context": {
      "get": {
        "description": "Returns a comprehensive business context snapshot in a single call,\noptimized for AI agents and MCP integrations. Includes business info,\ndefaults, plan usage, invoice series, recent activity, top clients,\nand current month financials.\n",
        "operationId": "getBusinessContext",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BusinessContext"
                }
              }
            },
            "description": "Business context data"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        },
        "summary": "Business context snapshot",
        "tags": [
          "Intelligence"
        ]
      }
    },
    "/v1/deposits": {
      "get": {
        "description": "Retrieve a paginated list of deposits with optional date range, client, and search filters.",
        "operationId": "listDeposits",
        "parameters": [
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "$ref": "#/components/parameters/Offset"
          },
          {
            "$ref": "#/components/parameters/Cursor"
          },
          {
            "$ref": "#/components/parameters/From"
          },
          {
            "$ref": "#/components/parameters/To"
          },
          {
            "$ref": "#/components/parameters/Search"
          },
          {
            "$ref": "#/components/parameters/Fields"
          },
          {
            "$ref": "#/components/parameters/FilterClientId"
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/PaginatedResponse"
                    },
                    {
                      "properties": {
                        "data": {
                          "items": {
                            "$ref": "#/components/schemas/Deposit"
                          },
                          "type": "array"
                        }
                      },
                      "type": "object"
                    }
                  ]
                }
              }
            },
            "description": "A paginated list of deposits"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        },
        "summary": "List deposits",
        "tags": [
          "Deposits"
        ]
      },
      "post": {
        "description": "Record a new client deposit or prepayment.",
        "operationId": "createDeposit",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DepositCreate"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Deposit"
                }
              }
            },
            "description": "Deposit created"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        },
        "summary": "Create a deposit",
        "tags": [
          "Deposits"
        ]
      }
    },
    "/v1/deposits/{depositId}": {
      "delete": {
        "description": "Permanently delete a deposit record.",
        "operationId": "deleteDeposit",
        "parameters": [
          {
            "$ref": "#/components/parameters/DepositId"
          }
        ],
        "responses": {
          "204": {
            "description": "Deposit deleted"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        },
        "summary": "Delete a deposit",
        "tags": [
          "Deposits"
        ]
      },
      "get": {
        "description": "Retrieve a single deposit by ID.",
        "operationId": "getDeposit",
        "parameters": [
          {
            "$ref": "#/components/parameters/DepositId"
          },
          {
            "$ref": "#/components/parameters/Fields"
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Deposit"
                }
              }
            },
            "description": "Deposit details"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        },
        "summary": "Get a deposit",
        "tags": [
          "Deposits"
        ]
      },
      "patch": {
        "description": "Update only the provided fields on an existing deposit.",
        "operationId": "patchDeposit",
        "parameters": [
          {
            "$ref": "#/components/parameters/DepositId"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DepositCreate"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Deposit"
                }
              }
            },
            "description": "Deposit updated"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        },
        "summary": "Partial update a deposit",
        "tags": [
          "Deposits"
        ]
      },
      "put": {
        "description": "Replace all fields on an existing deposit.",
        "operationId": "updateDeposit",
        "parameters": [
          {
            "$ref": "#/components/parameters/DepositId"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DepositCreate"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Deposit"
                }
              }
            },
            "description": "Deposit updated"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        },
        "summary": "Full update a deposit",
        "tags": [
          "Deposits"
        ]
      }
    },
    "/v1/deposits/{depositId}/apply": {
      "post": {
        "description": "Apply all or part of a deposit's remaining balance to a specific invoice.\nReturns an error if the requested amount exceeds the remaining balance or\nif the deposit has already been applied to the given invoice.\n",
        "operationId": "applyDeposit",
        "parameters": [
          {
            "$ref": "#/components/parameters/DepositId"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "properties": {
                  "amount": {
                    "description": "Amount to apply (must be positive and not exceed remaining balance)",
                    "example": 500,
                    "type": "number"
                  },
                  "invoiceId": {
                    "description": "ID of the invoice to apply the deposit to",
                    "example": "abc123def456",
                    "type": "string"
                  },
                  "invoiceNumber": {
                    "description": "Invoice number (for audit trail)",
                    "example": "FAC-2026-0042",
                    "type": "string"
                  }
                },
                "required": [
                  "invoiceId",
                  "invoiceNumber",
                  "amount"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "appliedAmount": {
                      "example": 500,
                      "type": "number"
                    },
                    "depositId": {
                      "example": "dep_abc123",
                      "type": "string"
                    },
                    "remainingBalance": {
                      "example": 250,
                      "type": "number"
                    },
                    "status": {
                      "enum": [
                        "active",
                        "partially_applied",
                        "fully_applied"
                      ],
                      "example": "partially_applied",
                      "type": "string"
                    },
                    "success": {
                      "example": true,
                      "type": "boolean"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Deposit applied successfully"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        },
        "summary": "Apply deposit to an invoice",
        "tags": [
          "Deposits"
        ]
      }
    },
    "/v1/deposits/{depositId}/refund": {
      "post": {
        "description": "Refund all or part of a deposit's remaining balance to the client.\nIf `amount` is omitted, the full remaining balance is refunded.\nReturns an error if the deposit is already fully refunded or if the\nrequested amount exceeds the remaining balance.\n",
        "operationId": "refundDeposit",
        "parameters": [
          {
            "$ref": "#/components/parameters/DepositId"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "properties": {
                  "amount": {
                    "description": "Amount to refund. Omit to refund the full remaining balance.",
                    "example": 250,
                    "type": "number"
                  }
                },
                "type": "object"
              }
            }
          }
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "depositId": {
                      "example": "dep_abc123",
                      "type": "string"
                    },
                    "refundedAmount": {
                      "example": 250,
                      "type": "number"
                    },
                    "remainingBalance": {
                      "example": 0,
                      "type": "number"
                    },
                    "success": {
                      "example": true,
                      "type": "boolean"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Deposit refunded successfully"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        },
        "summary": "Refund a deposit",
        "tags": [
          "Deposits"
        ]
      }
    },
    "/v1/expenses": {
      "get": {
        "description": "Retrieve a paginated list of expenses with optional date range and search filters.",
        "operationId": "listExpenses",
        "parameters": [
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "$ref": "#/components/parameters/Offset"
          },
          {
            "$ref": "#/components/parameters/Cursor"
          },
          {
            "$ref": "#/components/parameters/From"
          },
          {
            "$ref": "#/components/parameters/To"
          },
          {
            "$ref": "#/components/parameters/Search"
          },
          {
            "$ref": "#/components/parameters/Fields"
          },
          {
            "$ref": "#/components/parameters/FilterVendorId"
          },
          {
            "$ref": "#/components/parameters/FilterCategory"
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/PaginatedResponse"
                    },
                    {
                      "properties": {
                        "data": {
                          "items": {
                            "$ref": "#/components/schemas/Expense"
                          },
                          "type": "array"
                        }
                      },
                      "type": "object"
                    }
                  ]
                }
              }
            },
            "description": "A paginated list of expenses"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        },
        "summary": "List expenses",
        "tags": [
          "Expenses"
        ]
      },
      "post": {
        "description": "Record a new business expense.",
        "operationId": "createExpense",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ExpenseCreate"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Expense"
                }
              }
            },
            "description": "Expense created"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        },
        "summary": "Create an expense",
        "tags": [
          "Expenses"
        ]
      }
    },
    "/v1/expenses/{expenseId}": {
      "delete": {
        "description": "Permanently delete an expense record.",
        "operationId": "deleteExpense",
        "parameters": [
          {
            "$ref": "#/components/parameters/ExpenseId"
          }
        ],
        "responses": {
          "204": {
            "description": "Expense deleted"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        },
        "summary": "Delete an expense",
        "tags": [
          "Expenses"
        ]
      },
      "get": {
        "description": "Retrieve a single expense by ID.",
        "operationId": "getExpense",
        "parameters": [
          {
            "$ref": "#/components/parameters/ExpenseId"
          },
          {
            "$ref": "#/components/parameters/Fields"
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Expense"
                }
              }
            },
            "description": "Expense details"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        },
        "summary": "Get an expense",
        "tags": [
          "Expenses"
        ]
      },
      "patch": {
        "description": "Update only the provided fields on an existing expense record.",
        "operationId": "patchExpense",
        "parameters": [
          {
            "$ref": "#/components/parameters/ExpenseId"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ExpenseCreate"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Expense"
                }
              }
            },
            "description": "Expense updated"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        },
        "summary": "Partial update an expense",
        "tags": [
          "Expenses"
        ]
      },
      "put": {
        "description": "Replace all fields on an existing expense record.",
        "operationId": "updateExpense",
        "parameters": [
          {
            "$ref": "#/components/parameters/ExpenseId"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ExpenseCreate"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Expense"
                }
              }
            },
            "description": "Expense updated"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        },
        "summary": "Full update an expense",
        "tags": [
          "Expenses"
        ]
      }
    },
    "/v1/expenses/{expenseId}/billable": {
      "delete": {
        "description": "Remove the billable flag from an expense. The expense must not already\nbe invoiced — once invoiced, the billable flag cannot be removed.\n",
        "operationId": "unmarkExpenseBillable",
        "parameters": [
          {
            "$ref": "#/components/parameters/ExpenseId"
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "expenseId": {
                      "example": "exp_abc123",
                      "type": "string"
                    },
                    "success": {
                      "example": true,
                      "type": "boolean"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Billable flag removed"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        },
        "summary": "Remove billable flag from expense",
        "tags": [
          "Expenses"
        ]
      },
      "post": {
        "description": "Mark an expense as billable to a specific client, optionally with a markup\npercentage. The expense must not already be invoiced. Once billable, the\nexpense can be included in a client invoice.\n",
        "operationId": "markExpenseBillable",
        "parameters": [
          {
            "$ref": "#/components/parameters/ExpenseId"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "properties": {
                  "clientId": {
                    "description": "ID of the client to bill this expense to",
                    "example": "client_abc123",
                    "type": "string"
                  },
                  "markup": {
                    "description": "Markup percentage to apply when invoicing (e.g. 20 = 20% markup)",
                    "example": 20,
                    "maximum": 1000,
                    "minimum": 0,
                    "type": "number"
                  }
                },
                "required": [
                  "clientId"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "expenseId": {
                      "example": "exp_abc123",
                      "type": "string"
                    },
                    "success": {
                      "example": true,
                      "type": "boolean"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Expense marked as billable"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        },
        "summary": "Mark expense as billable",
        "tags": [
          "Expenses"
        ]
      }
    },
    "/v1/guests": {
      "get": {
        "description": "Retrieve compliance records for guest check-ins (document verification status).",
        "operationId": "listGuests",
        "parameters": [
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "$ref": "#/components/parameters/Offset"
          },
          {
            "$ref": "#/components/parameters/Cursor"
          },
          {
            "$ref": "#/components/parameters/Search"
          },
          {
            "$ref": "#/components/parameters/Fields"
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/PaginatedResponse"
                    },
                    {
                      "properties": {
                        "data": {
                          "items": {
                            "$ref": "#/components/schemas/Guest"
                          },
                          "type": "array"
                        }
                      },
                      "type": "object"
                    }
                  ]
                }
              }
            },
            "description": "A paginated list of guest compliance records"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        },
        "summary": "List guest compliance records",
        "tags": [
          "Guests"
        ]
      }
    },
    "/v1/guests/{guestId}": {
      "get": {
        "operationId": "getGuest",
        "parameters": [
          {
            "in": "path",
            "name": "guestId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/Fields"
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Guest"
                }
              }
            },
            "description": "Guest compliance record"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        },
        "summary": "Get a guest compliance record",
        "tags": [
          "Guests"
        ]
      }
    },
    "/v1/invoices": {
      "get": {
        "description": "Retrieve a paginated list of invoices with optional filters for status, date range, and search.",
        "operationId": "listInvoices",
        "parameters": [
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "$ref": "#/components/parameters/Offset"
          },
          {
            "$ref": "#/components/parameters/Cursor"
          },
          {
            "description": "Filter by invoice status",
            "in": "query",
            "name": "status",
            "schema": {
              "$ref": "#/components/schemas/InvoiceStatus"
            }
          },
          {
            "$ref": "#/components/parameters/From"
          },
          {
            "$ref": "#/components/parameters/To"
          },
          {
            "$ref": "#/components/parameters/Search"
          },
          {
            "$ref": "#/components/parameters/Fields"
          },
          {
            "$ref": "#/components/parameters/FilterClientId"
          },
          {
            "$ref": "#/components/parameters/FilterSeriesId"
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/PaginatedResponse"
                    },
                    {
                      "properties": {
                        "data": {
                          "items": {
                            "$ref": "#/components/schemas/Invoice"
                          },
                          "type": "array"
                        }
                      },
                      "type": "object"
                    }
                  ]
                }
              }
            },
            "description": "A paginated list of invoices"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        },
        "summary": "List invoices",
        "tags": [
          "Invoices"
        ]
      },
      "post": {
        "description": "Create a new invoice. The invoice is created in `draft` status by default.",
        "operationId": "createInvoice",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/InvoiceCreate"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Invoice"
                }
              }
            },
            "description": "Invoice created"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        },
        "summary": "Create an invoice",
        "tags": [
          "Invoices"
        ]
      }
    },
    "/v1/invoices/{invoiceId}": {
      "delete": {
        "description": "Delete an invoice. Draft invoices are permanently deleted (204).\nNon-draft invoices are soft-deleted (cancelled) to preserve VeriFactu\nSHA-256 hash chain integrity (RD 1007/2023 compliance), returning 200\nwith the cancelled document body.\n",
        "operationId": "deleteInvoice",
        "parameters": [
          {
            "$ref": "#/components/parameters/InvoiceId"
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "data": {
                      "properties": {
                        "cancelledVia": {
                          "example": "api",
                          "type": "string"
                        },
                        "id": {
                          "type": "string"
                        },
                        "status": {
                          "example": "cancelled",
                          "type": "string"
                        }
                      },
                      "type": "object"
                    },
                    "meta": {
                      "properties": {
                        "requestId": {
                          "type": "string"
                        },
                        "timestamp": {
                          "format": "date-time",
                          "type": "string"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Invoice soft-deleted (cancelled). Returned for non-draft invoices."
          },
          "204": {
            "description": "Invoice permanently deleted (draft invoices only)"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        },
        "summary": "Delete an invoice",
        "tags": [
          "Invoices"
        ]
      },
      "get": {
        "description": "Retrieve a single invoice by ID.",
        "operationId": "getInvoice",
        "parameters": [
          {
            "$ref": "#/components/parameters/InvoiceId"
          },
          {
            "$ref": "#/components/parameters/Fields"
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Invoice"
                }
              }
            },
            "description": "Invoice details"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        },
        "summary": "Get an invoice",
        "tags": [
          "Invoices"
        ]
      },
      "patch": {
        "description": "Update only the provided fields on an existing invoice. All fields are optional.",
        "operationId": "patchInvoice",
        "parameters": [
          {
            "$ref": "#/components/parameters/InvoiceId"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/InvoiceCreate"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Invoice"
                }
              }
            },
            "description": "Invoice updated"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        },
        "summary": "Partial update an invoice",
        "tags": [
          "Invoices"
        ]
      },
      "put": {
        "description": "Replace all fields on an existing invoice. All required fields must be provided.",
        "operationId": "updateInvoice",
        "parameters": [
          {
            "$ref": "#/components/parameters/InvoiceId"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/InvoiceCreate"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Invoice"
                }
              }
            },
            "description": "Invoice updated"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        },
        "summary": "Full update an invoice",
        "tags": [
          "Invoices"
        ]
      }
    },
    "/v1/invoices/{invoiceId}/credit-note": {
      "post": {
        "description": "Create a rectificative invoice (credit note) for an existing invoice.\nThe original invoice must not be in `draft` or `cancelled` status.\nThe credit note is created with `sent` status and negative line item amounts.\nThe `rectificativa` field is populated according to Spanish Facturae R-type codes.\n",
        "operationId": "createCreditNote",
        "parameters": [
          {
            "$ref": "#/components/parameters/InvoiceId"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "properties": {
                  "fullCredit": {
                    "default": true,
                    "description": "When true, issues a full credit (tipo S — sustitución).\nWhen false, issues a partial correction (tipo I — corrección por diferencias).\n",
                    "example": true,
                    "type": "boolean"
                  },
                  "issueDate": {
                    "description": "Issue date for the credit note. Defaults to today.",
                    "example": "2026-04-07",
                    "format": "date",
                    "type": "string"
                  },
                  "reason": {
                    "description": "Reason for the credit note",
                    "enum": [
                      "refund",
                      "discount",
                      "error",
                      "cancellation",
                      "other"
                    ],
                    "example": "error",
                    "type": "string"
                  },
                  "reasonDescription": {
                    "description": "Optional free-text description of the reason",
                    "example": "Incorrect unit price on line 2",
                    "maxLength": 500,
                    "type": "string"
                  }
                },
                "required": [
                  "reason"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "creditNote": {
                      "properties": {
                        "documentNumber": {
                          "example": "CN-FAC-2026-0042",
                          "type": "string"
                        },
                        "fullCredit": {
                          "example": true,
                          "type": "boolean"
                        },
                        "id": {
                          "description": "ID of the newly created credit note invoice",
                          "example": "cn_abc123",
                          "type": "string"
                        },
                        "originalInvoiceId": {
                          "example": "abc123def456",
                          "type": "string"
                        },
                        "reason": {
                          "example": "error",
                          "type": "string"
                        }
                      },
                      "type": "object"
                    },
                    "success": {
                      "example": true,
                      "type": "boolean"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Credit note created"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        },
        "summary": "Create a credit note",
        "tags": [
          "Invoices"
        ]
      }
    },
    "/v1/invoices/{invoiceId}/late-fee": {
      "post": {
        "description": "Calculate and apply a late payment fee to an overdue or sent invoice.\nUses the EU Late Payment Directive default rate of 8% per annum if `amount`\nis not specified. Can only be applied once per invoice.\n",
        "operationId": "applyLateFee",
        "parameters": [
          {
            "$ref": "#/components/parameters/InvoiceId"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "properties": {
                  "amount": {
                    "description": "Fixed fee amount. If omitted, auto-calculated at 8% p.a. on the invoice total.",
                    "example": 42.5,
                    "type": "number"
                  },
                  "daysOverdue": {
                    "description": "Override the number of overdue days used for auto-calculation. Defaults to actual days past due date.",
                    "example": 30,
                    "type": "integer"
                  }
                },
                "type": "object"
              }
            }
          }
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "daysOverdue": {
                      "example": 30,
                      "type": "integer"
                    },
                    "feeAmount": {
                      "description": "Fee amount applied",
                      "example": 42.5,
                      "type": "number"
                    },
                    "invoiceId": {
                      "example": "abc123def456",
                      "type": "string"
                    },
                    "success": {
                      "example": true,
                      "type": "boolean"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Late fee applied"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        },
        "summary": "Apply a late payment fee",
        "tags": [
          "Invoices"
        ]
      }
    },
    "/v1/invoices/{invoiceId}/paid": {
      "post": {
        "description": "Mark an invoice as paid. Optionally specify the payment date.",
        "operationId": "markInvoicePaid",
        "parameters": [
          {
            "$ref": "#/components/parameters/InvoiceId"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "properties": {
                  "paidDate": {
                    "description": "Payment date in ISO format. Defaults to today.",
                    "example": "2026-03-09",
                    "format": "date",
                    "type": "string"
                  }
                },
                "type": "object"
              }
            }
          }
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "paidAt": {
                      "format": "date",
                      "type": "string"
                    },
                    "status": {
                      "example": "paid",
                      "type": "string"
                    },
                    "success": {
                      "example": true,
                      "type": "boolean"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Invoice marked as paid"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        },
        "summary": "Mark invoice as paid",
        "tags": [
          "Invoices"
        ]
      }
    },
    "/v1/invoices/{invoiceId}/pdf": {
      "get": {
        "description": "Generate and download the invoice as a PDF document.",
        "operationId": "getInvoicePdf",
        "parameters": [
          {
            "$ref": "#/components/parameters/InvoiceId"
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/pdf": {
                "schema": {
                  "format": "binary",
                  "type": "string"
                }
              }
            },
            "description": "PDF document"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        },
        "summary": "Download invoice PDF",
        "tags": [
          "Invoices"
        ]
      }
    },
    "/v1/invoices/{invoiceId}/send": {
      "post": {
        "description": "Send the invoice to a recipient via email. If the invoice is in `draft` status, it will be automatically changed to `sent`.",
        "operationId": "sendInvoice",
        "parameters": [
          {
            "$ref": "#/components/parameters/InvoiceId"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SendEmailRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "messageId": {
                      "description": "Email provider message ID",
                      "type": "string"
                    },
                    "success": {
                      "example": true,
                      "type": "boolean"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Invoice sent"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Fiscal profile not configured"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        },
        "summary": "Send invoice by email",
        "tags": [
          "Invoices"
        ]
      }
    },
    "/v1/invoices/{invoiceId}/xml": {
      "get": {
        "description": "Download the Facturae 3.2.2 XML for an invoice. The XML is generated\nwhen the invoice is saved or sent. Returns 404 if the e-invoice XML\nhas not yet been generated for this invoice.\n",
        "operationId": "getInvoiceXml",
        "parameters": [
          {
            "$ref": "#/components/parameters/InvoiceId"
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/xml": {
                "schema": {
                  "format": "binary",
                  "type": "string"
                }
              }
            },
            "description": "E-invoice XML document"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        },
        "summary": "Download e-invoice XML",
        "tags": [
          "Invoices"
        ]
      }
    },
    "/v1/monthly": {
      "get": {
        "description": "Monthly financial summary with revenue breakdown (tax base, tax, IRPF),\nexpense breakdown (deductible, tax), profit (gross/net), invoice status\ncounts, top clients, expenses by category, and estimated tax liability\n(Modelo 303).\n",
        "operationId": "getMonthlySummary",
        "parameters": [
          {
            "description": "Month in YYYY-MM format. Defaults to current month.",
            "in": "query",
            "name": "month",
            "schema": {
              "example": "2026-03",
              "pattern": "^\\d{4}-\\d{2}$",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MonthlySummary"
                }
              }
            },
            "description": "Monthly financial summary"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        },
        "summary": "Monthly P&L",
        "tags": [
          "Intelligence"
        ]
      }
    },
    "/v1/products": {
      "get": {
        "description": "Retrieve a paginated list of products and services with optional search.",
        "operationId": "listProducts",
        "parameters": [
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "$ref": "#/components/parameters/Offset"
          },
          {
            "$ref": "#/components/parameters/Cursor"
          },
          {
            "$ref": "#/components/parameters/From"
          },
          {
            "$ref": "#/components/parameters/To"
          },
          {
            "$ref": "#/components/parameters/Search"
          },
          {
            "$ref": "#/components/parameters/Fields"
          },
          {
            "$ref": "#/components/parameters/FilterIsActive"
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/PaginatedResponse"
                    },
                    {
                      "properties": {
                        "data": {
                          "items": {
                            "$ref": "#/components/schemas/Product"
                          },
                          "type": "array"
                        }
                      },
                      "type": "object"
                    }
                  ]
                }
              }
            },
            "description": "A paginated list of products"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        },
        "summary": "List products",
        "tags": [
          "Products"
        ]
      },
      "post": {
        "description": "Add a new product or service to your catalog.",
        "operationId": "createProduct",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ProductCreate"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Product"
                }
              }
            },
            "description": "Product created"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        },
        "summary": "Create a product",
        "tags": [
          "Products"
        ]
      }
    },
    "/v1/products/{productId}": {
      "delete": {
        "description": "Permanently delete a product from your catalog.",
        "operationId": "deleteProduct",
        "parameters": [
          {
            "$ref": "#/components/parameters/ProductId"
          }
        ],
        "responses": {
          "204": {
            "description": "Product deleted"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        },
        "summary": "Delete a product",
        "tags": [
          "Products"
        ]
      },
      "get": {
        "description": "Retrieve a single product by ID.",
        "operationId": "getProduct",
        "parameters": [
          {
            "$ref": "#/components/parameters/ProductId"
          },
          {
            "$ref": "#/components/parameters/Fields"
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Product"
                }
              }
            },
            "description": "Product details"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        },
        "summary": "Get a product",
        "tags": [
          "Products"
        ]
      },
      "patch": {
        "description": "Update only the provided fields on an existing product or service.",
        "operationId": "patchProduct",
        "parameters": [
          {
            "$ref": "#/components/parameters/ProductId"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ProductCreate"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Product"
                }
              }
            },
            "description": "Product updated"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        },
        "summary": "Partial update a product",
        "tags": [
          "Products"
        ]
      },
      "put": {
        "description": "Replace all fields on an existing product or service.",
        "operationId": "updateProduct",
        "parameters": [
          {
            "$ref": "#/components/parameters/ProductId"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ProductCreate"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Product"
                }
              }
            },
            "description": "Product updated"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        },
        "summary": "Full update a product",
        "tags": [
          "Products"
        ]
      }
    },
    "/v1/properties": {
      "get": {
        "description": "Retrieve a paginated list of Stay properties.",
        "operationId": "listProperties",
        "parameters": [
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "$ref": "#/components/parameters/Offset"
          },
          {
            "$ref": "#/components/parameters/Cursor"
          },
          {
            "$ref": "#/components/parameters/Search"
          },
          {
            "$ref": "#/components/parameters/Fields"
          },
          {
            "in": "query",
            "name": "status",
            "schema": {
              "$ref": "#/components/schemas/PropertyStatus"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/PaginatedResponse"
                    },
                    {
                      "properties": {
                        "data": {
                          "items": {
                            "$ref": "#/components/schemas/Property"
                          },
                          "type": "array"
                        }
                      },
                      "type": "object"
                    }
                  ]
                }
              }
            },
            "description": "A paginated list of properties"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        },
        "summary": "List properties",
        "tags": [
          "Properties"
        ]
      },
      "post": {
        "operationId": "createProperty",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PropertyCreate"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Property"
                }
              }
            },
            "description": "Property created"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        },
        "summary": "Create a property",
        "tags": [
          "Properties"
        ]
      }
    },
    "/v1/properties/{propertyId}": {
      "get": {
        "operationId": "getProperty",
        "parameters": [
          {
            "in": "path",
            "name": "propertyId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/Fields"
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Property"
                }
              }
            },
            "description": "Property details"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        },
        "summary": "Get a property",
        "tags": [
          "Properties"
        ]
      },
      "patch": {
        "operationId": "updateProperty",
        "parameters": [
          {
            "in": "path",
            "name": "propertyId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PropertyCreate"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Property"
                }
              }
            },
            "description": "Property updated"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        },
        "summary": "Update a property",
        "tags": [
          "Properties"
        ]
      }
    },
    "/v1/quarterly": {
      "get": {
        "description": "Quarterly tax preparation data including Modelo 303 (VAT) and\nModelo 130 (quarterly income payment) pre-filled figures.\nIncludes base imponible, cuotas, and estimated payments.\n",
        "operationId": "getQuarterlySummary",
        "parameters": [
          {
            "description": "Quarter in YYYY-Q1 format. Defaults to current quarter.",
            "in": "query",
            "name": "quarter",
            "schema": {
              "example": "2026-Q1",
              "pattern": "^\\d{4}-Q[1-4]$",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/QuarterlySummary"
                }
              }
            },
            "description": "Quarterly tax summary"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        },
        "summary": "Quarterly tax figures",
        "tags": [
          "Intelligence"
        ]
      }
    },
    "/v1/quotes": {
      "get": {
        "description": "Retrieve a paginated list of quotes with optional filters for status, date range, and search.",
        "operationId": "listQuotes",
        "parameters": [
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "$ref": "#/components/parameters/Offset"
          },
          {
            "$ref": "#/components/parameters/Cursor"
          },
          {
            "description": "Filter by quote status",
            "in": "query",
            "name": "status",
            "schema": {
              "$ref": "#/components/schemas/QuoteStatus"
            }
          },
          {
            "$ref": "#/components/parameters/From"
          },
          {
            "$ref": "#/components/parameters/To"
          },
          {
            "$ref": "#/components/parameters/Search"
          },
          {
            "$ref": "#/components/parameters/Fields"
          },
          {
            "$ref": "#/components/parameters/FilterClientId"
          },
          {
            "$ref": "#/components/parameters/FilterSeriesId"
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/PaginatedResponse"
                    },
                    {
                      "properties": {
                        "data": {
                          "items": {
                            "$ref": "#/components/schemas/Quote"
                          },
                          "type": "array"
                        }
                      },
                      "type": "object"
                    }
                  ]
                }
              }
            },
            "description": "A paginated list of quotes"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        },
        "summary": "List quotes",
        "tags": [
          "Quotes"
        ]
      },
      "post": {
        "description": "Create a new quote. The quote is created in `draft` status by default.",
        "operationId": "createQuote",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/QuoteCreate"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Quote"
                }
              }
            },
            "description": "Quote created"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        },
        "summary": "Create a quote",
        "tags": [
          "Quotes"
        ]
      }
    },
    "/v1/quotes/{quoteId}": {
      "delete": {
        "description": "Delete a quote. Draft quotes are permanently deleted (204).\nNon-draft quotes are soft-deleted (cancelled) to preserve VeriFactu\nhash chain integrity, returning 200 with the cancelled document body.\n",
        "operationId": "deleteQuote",
        "parameters": [
          {
            "$ref": "#/components/parameters/QuoteId"
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "data": {
                      "properties": {
                        "cancelledVia": {
                          "example": "api",
                          "type": "string"
                        },
                        "id": {
                          "type": "string"
                        },
                        "status": {
                          "example": "cancelled",
                          "type": "string"
                        }
                      },
                      "type": "object"
                    },
                    "meta": {
                      "properties": {
                        "requestId": {
                          "type": "string"
                        },
                        "timestamp": {
                          "format": "date-time",
                          "type": "string"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Quote soft-deleted (cancelled). Returned for non-draft quotes."
          },
          "204": {
            "description": "Quote permanently deleted (draft quotes only)"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        },
        "summary": "Delete a quote",
        "tags": [
          "Quotes"
        ]
      },
      "get": {
        "description": "Retrieve a single quote by ID.",
        "operationId": "getQuote",
        "parameters": [
          {
            "$ref": "#/components/parameters/QuoteId"
          },
          {
            "$ref": "#/components/parameters/Fields"
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Quote"
                }
              }
            },
            "description": "Quote details"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        },
        "summary": "Get a quote",
        "tags": [
          "Quotes"
        ]
      },
      "patch": {
        "description": "Update only the provided fields on an existing quote.",
        "operationId": "patchQuote",
        "parameters": [
          {
            "$ref": "#/components/parameters/QuoteId"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/QuoteCreate"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Quote"
                }
              }
            },
            "description": "Quote updated"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        },
        "summary": "Partial update a quote",
        "tags": [
          "Quotes"
        ]
      },
      "put": {
        "description": "Replace all fields on an existing quote.",
        "operationId": "updateQuote",
        "parameters": [
          {
            "$ref": "#/components/parameters/QuoteId"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/QuoteCreate"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Quote"
                }
              }
            },
            "description": "Quote updated"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        },
        "summary": "Full update a quote",
        "tags": [
          "Quotes"
        ]
      }
    },
    "/v1/quotes/{quoteId}/pdf": {
      "get": {
        "description": "Generate and download the quote as a PDF document.",
        "operationId": "getQuotePdf",
        "parameters": [
          {
            "$ref": "#/components/parameters/QuoteId"
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/pdf": {
                "schema": {
                  "format": "binary",
                  "type": "string"
                }
              }
            },
            "description": "PDF document"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        },
        "summary": "Download quote PDF",
        "tags": [
          "Quotes"
        ]
      }
    },
    "/v1/quotes/{quoteId}/send": {
      "post": {
        "description": "Send the quote to a recipient via email. If the quote is in `draft` status, it will be automatically changed to `sent`.",
        "operationId": "sendQuote",
        "parameters": [
          {
            "$ref": "#/components/parameters/QuoteId"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SendEmailRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "messageId": {
                      "description": "Email provider message ID",
                      "type": "string"
                    },
                    "success": {
                      "example": true,
                      "type": "boolean"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Quote sent"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Fiscal profile not configured"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        },
        "summary": "Send quote by email",
        "tags": [
          "Quotes"
        ]
      }
    },
    "/v1/reservations": {
      "get": {
        "description": "Retrieve a paginated list of Stay reservations with optional filters.",
        "operationId": "listReservations",
        "parameters": [
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "$ref": "#/components/parameters/Offset"
          },
          {
            "$ref": "#/components/parameters/Cursor"
          },
          {
            "$ref": "#/components/parameters/From"
          },
          {
            "$ref": "#/components/parameters/To"
          },
          {
            "$ref": "#/components/parameters/Search"
          },
          {
            "$ref": "#/components/parameters/Fields"
          },
          {
            "in": "query",
            "name": "status",
            "schema": {
              "$ref": "#/components/schemas/ReservationStatus"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/PaginatedResponse"
                    },
                    {
                      "properties": {
                        "data": {
                          "items": {
                            "$ref": "#/components/schemas/Reservation"
                          },
                          "type": "array"
                        }
                      },
                      "type": "object"
                    }
                  ]
                }
              }
            },
            "description": "A paginated list of reservations"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        },
        "summary": "List reservations",
        "tags": [
          "Reservations"
        ]
      },
      "post": {
        "operationId": "createReservation",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ReservationCreate"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Reservation"
                }
              }
            },
            "description": "Reservation created"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        },
        "summary": "Create a reservation",
        "tags": [
          "Reservations"
        ]
      }
    },
    "/v1/reservations/{reservationId}": {
      "get": {
        "operationId": "getReservation",
        "parameters": [
          {
            "in": "path",
            "name": "reservationId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/Fields"
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Reservation"
                }
              }
            },
            "description": "Reservation details"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        },
        "summary": "Get a reservation",
        "tags": [
          "Reservations"
        ]
      },
      "patch": {
        "operationId": "updateReservation",
        "parameters": [
          {
            "in": "path",
            "name": "reservationId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ReservationCreate"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Reservation"
                }
              }
            },
            "description": "Reservation updated"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        },
        "summary": "Update a reservation",
        "tags": [
          "Reservations"
        ]
      }
    },
    "/v1/summary": {
      "get": {
        "description": "Get an aggregated financial summary including revenue, expenses, profit,\nentity counts, and invoice status breakdown. Supports optional date range filtering.\n",
        "operationId": "getSummary",
        "parameters": [
          {
            "$ref": "#/components/parameters/From"
          },
          {
            "$ref": "#/components/parameters/To"
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Summary"
                }
              }
            },
            "description": "Financial summary"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        },
        "summary": "Financial summary",
        "tags": [
          "Summary"
        ]
      }
    },
    "/v1/vendors": {
      "get": {
        "description": "Retrieve a paginated list of vendors.",
        "operationId": "listVendors",
        "parameters": [
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "$ref": "#/components/parameters/Offset"
          },
          {
            "$ref": "#/components/parameters/Cursor"
          },
          {
            "$ref": "#/components/parameters/From"
          },
          {
            "$ref": "#/components/parameters/To"
          },
          {
            "$ref": "#/components/parameters/Search"
          },
          {
            "$ref": "#/components/parameters/Fields"
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/PaginatedResponse"
                    },
                    {
                      "properties": {
                        "data": {
                          "items": {
                            "$ref": "#/components/schemas/Vendor"
                          },
                          "type": "array"
                        }
                      },
                      "type": "object"
                    }
                  ]
                }
              }
            },
            "description": "A paginated list of vendors"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        },
        "summary": "List vendors",
        "tags": [
          "Vendors"
        ]
      },
      "post": {
        "description": "Add a new vendor to your database.",
        "operationId": "createVendor",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/VendorCreate"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Vendor"
                }
              }
            },
            "description": "Vendor created"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        },
        "summary": "Create a vendor",
        "tags": [
          "Vendors"
        ]
      }
    },
    "/v1/vendors/{vendorId}": {
      "delete": {
        "description": "Permanently delete a vendor from your database.",
        "operationId": "deleteVendor",
        "parameters": [
          {
            "$ref": "#/components/parameters/VendorId"
          }
        ],
        "responses": {
          "204": {
            "description": "Vendor deleted"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        },
        "summary": "Delete a vendor",
        "tags": [
          "Vendors"
        ]
      },
      "get": {
        "description": "Retrieve a single vendor by ID.",
        "operationId": "getVendor",
        "parameters": [
          {
            "$ref": "#/components/parameters/VendorId"
          },
          {
            "$ref": "#/components/parameters/Fields"
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Vendor"
                }
              }
            },
            "description": "Vendor details"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        },
        "summary": "Get a vendor",
        "tags": [
          "Vendors"
        ]
      },
      "patch": {
        "description": "Update only the provided fields on an existing vendor.",
        "operationId": "patchVendor",
        "parameters": [
          {
            "$ref": "#/components/parameters/VendorId"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/VendorCreate"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Vendor"
                }
              }
            },
            "description": "Vendor updated"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        },
        "summary": "Partial update a vendor",
        "tags": [
          "Vendors"
        ]
      },
      "put": {
        "description": "Replace all fields on an existing vendor.",
        "operationId": "updateVendor",
        "parameters": [
          {
            "$ref": "#/components/parameters/VendorId"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/VendorCreate"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Vendor"
                }
              }
            },
            "description": "Vendor updated"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        },
        "summary": "Full update a vendor",
        "tags": [
          "Vendors"
        ]
      }
    },
    "/v1/webhooks": {
      "get": {
        "description": "Retrieve all webhook subscriptions for the authenticated user.",
        "operationId": "listWebhooks",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "data": {
                      "items": {
                        "$ref": "#/components/schemas/Webhook"
                      },
                      "type": "array"
                    },
                    "total": {
                      "type": "integer"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "List of webhooks"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        },
        "summary": "List webhooks",
        "tags": [
          "Webhooks"
        ]
      },
      "post": {
        "description": "Register a new webhook subscription to receive event notifications.",
        "operationId": "createWebhook",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WebhookCreate"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/Webhook"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Webhook created"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        },
        "summary": "Create a webhook",
        "tags": [
          "Webhooks"
        ]
      }
    },
    "/v1/webhooks/{webhookId}": {
      "delete": {
        "description": "Permanently delete a webhook subscription.",
        "operationId": "deleteWebhook",
        "parameters": [
          {
            "$ref": "#/components/parameters/WebhookId"
          }
        ],
        "responses": {
          "204": {
            "description": "Webhook deleted"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        },
        "summary": "Delete a webhook",
        "tags": [
          "Webhooks"
        ]
      },
      "get": {
        "description": "Retrieve a single webhook subscription by ID.",
        "operationId": "getWebhook",
        "parameters": [
          {
            "$ref": "#/components/parameters/WebhookId"
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/Webhook"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Webhook details"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        },
        "summary": "Get a webhook",
        "tags": [
          "Webhooks"
        ]
      },
      "patch": {
        "description": "Update only the provided fields on an existing webhook subscription.",
        "operationId": "patchWebhook",
        "parameters": [
          {
            "$ref": "#/components/parameters/WebhookId"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WebhookUpdate"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/Webhook"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Webhook updated"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        },
        "summary": "Partial update a webhook",
        "tags": [
          "Webhooks"
        ]
      },
      "put": {
        "description": "Replace all fields on an existing webhook subscription.",
        "operationId": "updateWebhook",
        "parameters": [
          {
            "$ref": "#/components/parameters/WebhookId"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WebhookUpdate"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/Webhook"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Webhook updated"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        },
        "summary": "Full update a webhook",
        "tags": [
          "Webhooks"
        ]
      }
    },
    "/v1/{resource}/batch": {
      "post": {
        "description": "Create multiple resources in a single request. The request body must be\nan array of items (max 50). Each item is validated independently.\nReturns 201 if all succeed, 207 if partially successful, 400 if all fail.\n",
        "operationId": "batchCreate",
        "parameters": [
          {
            "description": "Resource type to batch create",
            "in": "path",
            "name": "resource",
            "required": true,
            "schema": {
              "enum": [
                "invoices",
                "expenses",
                "clients",
                "vendors",
                "products",
                "quotes"
              ],
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "items": {
                  "type": "object"
                },
                "maxItems": 50,
                "minItems": 1,
                "type": "array"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BatchResponse"
                }
              }
            },
            "description": "All items created successfully"
          },
          "207": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BatchResponse"
                }
              }
            },
            "description": "Partial success (some items failed validation)"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        },
        "summary": "Batch create resources",
        "tags": [
          "Batch"
        ]
      }
    },
    "/webhooks/resend-inbound": {
      "post": {
        "description": "Receives inbound emails forwarded to `receipts@<workspace-slug>.frihet.io` via Resend.\nVerifies the Svix webhook signature, extracts PDF/image attachments, and queues\neach one in `receipt_queue/{workspaceUid}/items/{id}` for downstream OCR processing.\n\nThis endpoint is called by Resend's inbound routing — not by API consumers.\nSignature verification uses HMAC-SHA256 with the `RESEND_INBOUND_WEBHOOK_SECRET`\nenvironment variable. Header format follows Svix:\n`svix-id`, `svix-timestamp`, `svix-signature`.\n\n**Supported attachment MIME types:** `application/pdf`, `image/jpeg`, `image/png`,\n`image/webp`, `image/heic`, `image/heif`, `image/tiff`.\n",
        "operationId": "resendInbound",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ResendInboundPayload"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "queued": {
                      "description": "Number of attachments queued for OCR",
                      "example": 2,
                      "type": "integer"
                    },
                    "skipped": {
                      "description": "Number of attachments skipped (unsupported type or no content)",
                      "example": 0,
                      "type": "integer"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Email processed. Returns count of queued attachments."
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Invalid destination address format"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Missing or invalid Svix signature headers"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Workspace slug not found"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        },
        "security": [],
        "summary": "Resend inbound email webhook",
        "tags": [
          "Webhooks"
        ]
      }
    }
  },
  "security": [
    {
      "ApiKeyAuth": []
    }
  ],
  "servers": [
    {
      "description": "Frihet production API",
      "url": "https://api.frihet.io/v1"
    }
  ],
  "tags": [
    {
      "description": "Create, read, update, and delete invoices. Includes PDF generation, email sending, and payment tracking.",
      "name": "Invoices"
    },
    {
      "description": "Manage business expenses with categories, tax deductions, and receipt attachments.",
      "name": "Expenses"
    },
    {
      "description": "Manage your client database with contact details, tax IDs, and addresses.",
      "name": "Clients"
    },
    {
      "description": "Product and service catalog with pricing, tax rates, and SKUs.",
      "name": "Products"
    },
    {
      "description": "Create and manage quotes with PDF generation and email delivery. Convert accepted quotes to invoices.",
      "name": "Quotes"
    },
    {
      "description": "Manage your vendor database with contact details, tax IDs, and addresses.",
      "name": "Vendors"
    },
    {
      "description": "Financial dashboard data including revenue, expenses, and profit aggregations.",
      "name": "Summary"
    },
    {
      "description": "AI-optimized endpoints providing business context, monthly P&L, and quarterly tax figures in a single call.",
      "name": "Intelligence"
    },
    {
      "description": "CRUD endpoints for managing webhook subscriptions that receive real-time event notifications.",
      "name": "Webhooks"
    },
    {
      "description": "Contact persons associated with a client. Manage multiple contacts per client for CRM.",
      "name": "Contacts"
    },
    {
      "description": "Immutable activity timeline for a client. System activities are auto-generated; manual activities can be created via API.",
      "name": "Activities"
    },
    {
      "description": "Free-form notes attached to a client.",
      "name": "Notes"
    },
    {
      "description": "Manage client deposits and prepayments. Apply deposits against invoices or process refunds.",
      "name": "Deposits"
    },
    {
      "description": "Batch creation of resources (up to 50 items per request).",
      "name": "Batch"
    },
    {
      "description": "Frihet Stay: Manage vacation rental reservations with guest info, dates, and compliance tracking.",
      "name": "Reservations"
    },
    {
      "description": "Frihet Stay: Manage rental properties with owner info, capacity, and licensing.",
      "name": "Properties"
    },
    {
      "description": "Frihet Stay: Read compliance records for guest check-in (document verification, police reports).",
      "name": "Guests"
    },
    {
      "description": "Frihet Stay: Manage channel connections (iCal feeds) for calendar sync with OTAs.",
      "name": "Channels"
    }
  ]
}