{"openapi":"3.0.3","info":{"title":"Condie Public API","version":"1.0.0","description":"Public REST API for Condie, a multi-tenant property\nmanagement SaaS for Portuguese condominiums.\n\n**Authentication.** Every request needs `Authorization: Bearer <api-key>`.\nAPI keys are scoped (`buildings:read`, `owners:read`,\n`payments:read`, `expenses:read`, `financialDocuments:read`,\n`documentLinks:read`, or `*` for all); requesting a resource your\nkey isn't scoped for returns 403.\n\n**Org isolation.** API keys are bound to an organization; data\nreturned is automatically filtered to that organization.\n\n**Rate limiting.** Requests are rate-limited per key (default 100 per\nminute). Over the limit the API answers 429 with `retryAfterMs`.\n\n**Pagination.** Ledger endpoints are cursor-paginated: pass the\n`nextCursor` of one page as `?cursor=` of the next; `?limit=`\nclamps to [1, 200], default 50.\n\n**Error format.** Errors return `{ \"error\": \"<message>\" }` with a 4xx\nstatus. See ADR 0005 for the contract.\n\n**Coverage.** This document describes every `/api/v1` endpoint; the\ntyped client in `packages/sdk` is generated from it.\n\nSource: https://github.com/JoseUrzal/condie","contact":{"name":"Condie","email":"joseurzalmagalhaes@gmail.com","url":"https://condie.pt"},"license":{"name":"AGPL-3.0","url":"https://github.com/JoseUrzal/condie/blob/main/LICENSE"}},"servers":[{"url":"https://api.condie.pt","description":"Production"},{"url":"http://localhost:3000","description":"Local dev"}],"tags":[{"name":"Buildings","description":"Condominium buildings"},{"name":"Owners","description":"Owners and per-unit residents"},{"name":"Payments","description":"Receipts and payment records"},{"name":"Expenses","description":"Supplier invoices and outflows"},{"name":"Issues","description":"Maintenance issues"},{"name":"Financial documents","description":"The FinancialDocument ledger and its reconciliation links"},{"name":"Meta","description":"API self-description"}],"components":{"securitySchemes":{"ApiKey":{"type":"http","scheme":"bearer","description":"API key issued by the manager dashboard. Scoped by capability."}},"schemas":{"BuildingList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Building"}},"count":{"type":"integer","minimum":0}},"required":["data","count"]},"Building":{"type":"object","properties":{"id":{"type":"string","description":"Stable CUID identifier"},"name":{"type":"string"},"address":{"type":"string"},"nif":{"type":"string","nullable":true,"description":"Portuguese tax ID (NIF), null when not provided"},"createdAt":{"type":"string","format":"date-time","description":"ISO 8601 timestamp"}},"required":["id","name","address","nif","createdAt"]},"Error":{"type":"object","properties":{"error":{"type":"string","description":"Human-readable error message in Portuguese, always a string"}},"required":["error"]},"RateLimited":{"type":"object","properties":{"error":{"type":"string"},"retryAfterMs":{"type":"integer","minimum":0,"description":"Milliseconds until the per-key window resets"}},"required":["error","retryAfterMs"]},"BuildingSingle":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Building"}},"required":["data"]},"UnitList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Unit"}},"count":{"type":"integer","minimum":0}},"required":["data","count"]},"Unit":{"type":"object","properties":{"id":{"type":"string"},"number":{"type":"string","description":"Fraction label, e.g. \"1A\""},"permilagem":{"type":"number","nullable":true,"description":"Share in permilage (parts per thousand)"}},"required":["id","number","permilagem"]},"OwnerList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Owner"}},"count":{"type":"integer","minimum":0}},"required":["data","count"]},"Owner":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"email":{"type":"string","nullable":true,"description":"Null unless the key also has the owners:contact scope"},"phone":{"type":"string","nullable":true,"description":"Null unless the key also has the owners:contact scope"},"credit":{"type":"number","description":"Prepaid credit in EUR"},"unit":{"type":"object","nullable":true,"properties":{"number":{"type":"string"}},"required":["number"]},"balance":{"type":"number","description":"Ledger balance in EUR from the FinancialDocument ledger; positive means the owner owes"}},"required":["id","name","email","phone","credit","unit","balance"]},"ArrearsList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/BuildingArrears"}},"count":{"type":"integer","minimum":0,"description":"Number of buildings returned"}},"required":["data","count"]},"BuildingArrears":{"type":"object","properties":{"buildingId":{"type":"string"},"buildingName":{"type":"string"},"thresholdMonths":{"type":"integer","minimum":0,"description":"Months unpaid before an owner counts as in arrears (the building's setting, or ?minMonths)"},"count":{"type":"integer","minimum":0},"total":{"type":"number","description":"Sum of the debtors' balances in EUR"},"aging":{"$ref":"#/components/schemas/AgingLadder"},"debtors":{"type":"array","items":{"$ref":"#/components/schemas/ArrearsDebtor"}}},"required":["buildingId","buildingName","thresholdMonths","count","total","aging","debtors"]},"AgingLadder":{"type":"object","properties":{"0-30":{"type":"number"},"31-60":{"type":"number"},"61-90":{"type":"number"},"91-180":{"type":"number"},"180+":{"type":"number"}},"required":["0-30","31-60","61-90","91-180","180+"],"description":"Amount owed per rung of the aging ladder, in days past the oldest unpaid due date"},"ArrearsDebtor":{"type":"object","properties":{"ownerId":{"type":"string"},"ownerName":{"type":"string"},"ownerEmail":{"type":"string","nullable":true},"ownerPhone":{"type":"string","nullable":true},"unitId":{"type":"string"},"unitNumber":{"type":"string","nullable":true,"description":"Fraction label; suffixed \"(anterior)\" when the debtor no longer holds it"},"balance":{"type":"number","description":"Outstanding amount in EUR"},"oldestUnpaidChargeDate":{"type":"string","format":"date-time","description":"ISO 8601 timestamp"},"oldestUnpaidDueDate":{"type":"string","format":"date-time","description":"ISO 8601 timestamp"},"daysOverdue":{"type":"integer","minimum":0},"monthsOverdue":{"type":"integer","minimum":0},"agingBucket":{"type":"string","enum":["0-30","31-60","61-90","91-180","180+"]},"escalationPaused":{"type":"boolean","description":"Automatic collection reminders paused by the manager"}},"required":["ownerId","ownerName","ownerEmail","ownerPhone","unitId","unitNumber","balance","oldestUnpaidChargeDate","oldestUnpaidDueDate","daysOverdue","monthsOverdue","agingBucket","escalationPaused"]},"BalancesSummary":{"type":"object","properties":{"data":{"type":"object","properties":{"buildings":{"type":"array","items":{"$ref":"#/components/schemas/BuildingBalances"}},"totals":{"type":"object","properties":{"buildings":{"type":"integer","minimum":0},"owners":{"type":"integer","minimum":0},"debtors":{"type":"integer","minimum":0},"totalOwed":{"type":"number"},"totalCredit":{"type":"number"},"net":{"type":"number"},"inArrears":{"$ref":"#/components/schemas/InArrearsTotals"}},"required":["buildings","owners","debtors","totalOwed","totalCredit","net","inArrears"]}},"required":["buildings","totals"]}},"required":["data"]},"BuildingBalances":{"type":"object","properties":{"buildingId":{"type":"string"},"buildingName":{"type":"string"},"owners":{"type":"integer","minimum":0,"description":"Owners with at least one ledger document"},"debtors":{"type":"integer","minimum":0,"description":"Owners with a positive balance"},"totalOwed":{"type":"number","description":"Sum of the positive balances in EUR"},"totalCredit":{"type":"number","description":"Sum of the negative balances, as a positive number"},"net":{"type":"number","description":"totalOwed minus totalCredit"},"inArrears":{"$ref":"#/components/schemas/InArrearsTotals"}},"required":["buildingId","buildingName","owners","debtors","totalOwed","totalCredit","net","inArrears"]},"InArrearsTotals":{"type":"object","properties":{"count":{"type":"integer","minimum":0},"total":{"type":"number"}},"required":["count","total"],"description":"The debtors past the building's arrears threshold"},"PaymentList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Payment"}},"count":{"type":"integer","minimum":0}},"required":["data","count"]},"Payment":{"type":"object","properties":{"id":{"type":"string","description":"Receipt document id"},"amount":{"type":"number"},"method":{"type":"string","nullable":true,"description":"Payment method recorded on the receipt"},"month":{"type":"integer"},"year":{"type":"integer"},"paidAt":{"type":"string","format":"date-time","description":"ISO 8601 timestamp"},"ownerId":{"type":"string","nullable":true}},"required":["id","amount","method","month","year","paidAt","ownerId"]},"ExpenseList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Expense"}},"count":{"type":"integer","minimum":0}},"required":["data","count"]},"Expense":{"type":"object","properties":{"id":{"type":"string","description":"Supplier document id"},"description":{"type":"string"},"amount":{"type":"number"},"category":{"type":"string","description":"Charge type, or \"other\" when not set"},"date":{"type":"string","format":"date-time","description":"ISO 8601 timestamp"}},"required":["id","description","amount","category","date"]},"IssueList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Issue"}},"count":{"type":"integer","minimum":0}},"required":["data","count"]},"Issue":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"description":{"type":"string","nullable":true},"status":{"type":"string"},"category":{"type":"string","nullable":true},"urgent":{"type":"boolean"},"createdAt":{"type":"string","format":"date-time","description":"ISO 8601 timestamp"}},"required":["id","title","description","status","category","urgent","createdAt"]},"FinancialDocumentList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/FinancialDocument"}},"count":{"type":"integer","minimum":0},"nextCursor":{"type":"string","nullable":true,"description":"Pass as ?cursor= to fetch the next page; null on the last page"}},"required":["data","count","nextCursor"]},"FinancialDocument":{"type":"object","properties":{"id":{"type":"string"},"documentNumber":{"type":"string"},"type":{"type":"string","description":"charge, receipt, credit, void, supplier_invoice, supplier_payment, ..."},"status":{"type":"string","description":"active, cancelled, ..."},"issuedAt":{"type":"string","format":"date-time","description":"ISO 8601 timestamp"},"dueDate":{"type":"string","nullable":true,"format":"date-time"},"amount":{"type":"number"},"description":{"type":"string"},"ownerId":{"type":"string","nullable":true},"unitId":{"type":"string","nullable":true},"supplierId":{"type":"string","nullable":true},"chargeType":{"type":"string","nullable":true},"paymentMethod":{"type":"string","nullable":true},"paymentReference":{"type":"string","nullable":true},"paidAt":{"type":"string","nullable":true,"format":"date-time"},"reconciledAt":{"type":"string","nullable":true,"format":"date-time"},"atcud":{"type":"string","nullable":true,"description":"AT unique document code, once fiscally emitted"},"qrCodeData":{"type":"string","nullable":true},"saftHash":{"type":"string","nullable":true},"series":{"type":"string","nullable":true},"emissionStatus":{"type":"string","nullable":true},"emittedAt":{"type":"string","nullable":true,"format":"date-time"},"voidedAt":{"type":"string","nullable":true,"format":"date-time"},"voidReason":{"type":"string","nullable":true},"createdAt":{"type":"string","format":"date-time","description":"ISO 8601 timestamp"}},"required":["id","documentNumber","type","status","issuedAt","dueDate","amount","description","ownerId","unitId","supplierId","chargeType","paymentMethod","paymentReference","paidAt","reconciledAt","atcud","qrCodeData","saftHash","series","emissionStatus","emittedAt","voidedAt","voidReason","createdAt"]},"FinancialDocumentSingle":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/FinancialDocumentDetail"}},"required":["data"]},"FinancialDocumentDetail":{"allOf":[{"$ref":"#/components/schemas/FinancialDocument"},{"type":"object","properties":{"condominiumId":{"type":"string"},"sourceLinks":{"type":"array","items":{"$ref":"#/components/schemas/SourceLink"},"description":"Links where this document is the source (e.g. a receipt and the charges it pays)"},"targetLinks":{"type":"array","items":{"$ref":"#/components/schemas/TargetLink"},"description":"Links where this document is the target (e.g. the receipts paying this charge)"}},"required":["condominiumId","sourceLinks","targetLinks"]}]},"SourceLink":{"type":"object","properties":{"id":{"type":"string"},"targetDocId":{"type":"string"},"amount":{"type":"number"},"createdAt":{"type":"string","format":"date-time","description":"ISO 8601 timestamp"},"targetDoc":{"$ref":"#/components/schemas/LinkedDocumentSummary"}},"required":["id","targetDocId","amount","createdAt","targetDoc"]},"LinkedDocumentSummary":{"type":"object","properties":{"documentNumber":{"type":"string"},"type":{"type":"string"},"amount":{"type":"number"}},"required":["documentNumber","type","amount"]},"TargetLink":{"type":"object","properties":{"id":{"type":"string"},"sourceDocId":{"type":"string"},"amount":{"type":"number"},"createdAt":{"type":"string","format":"date-time","description":"ISO 8601 timestamp"},"sourceDoc":{"$ref":"#/components/schemas/LinkedDocumentSummary"}},"required":["id","sourceDocId","amount","createdAt","sourceDoc"]},"DocumentLinkList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/DocumentLink"}},"count":{"type":"integer","minimum":0},"nextCursor":{"type":"string","nullable":true}},"required":["data","count","nextCursor"]},"DocumentLink":{"type":"object","properties":{"id":{"type":"string"},"sourceDocId":{"type":"string"},"targetDocId":{"type":"string"},"amount":{"type":"number","description":"Amount of the source document applied to the target"},"createdAt":{"type":"string","format":"date-time","description":"ISO 8601 timestamp"}},"required":["id","sourceDocId","targetDocId","amount","createdAt"]},"ApiDescription":{"type":"object","properties":{"name":{"type":"string"},"version":{"type":"string"},"baseUrl":{"type":"string"},"openapi":{"type":"string","description":"Path of the machine-readable OpenAPI document"},"authentication":{"type":"string"},"scopes":{"type":"array","items":{"type":"string"}},"endpoints":{"type":"array","items":{"type":"object","properties":{"method":{"type":"string"},"path":{"type":"string"},"scope":{"type":"string","nullable":true,"description":"Scope the key needs; null when any valid key may call it"},"description":{"type":"string"}},"required":["method","path","scope","description"]}},"pagination":{"type":"string"},"rateLimit":{"type":"string"}},"required":["name","version","baseUrl","openapi","authentication","scopes","endpoints","pagination","rateLimit"]}},"parameters":{}},"paths":{"/v1/buildings":{"get":{"tags":["Buildings"],"summary":"List buildings","description":"Returns every building in the calling key's organization, up to 500.","security":[{"ApiKey":["buildings:read"]}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildingList"}}}},"401":{"description":"Missing, invalid, deactivated or expired API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"API key lacks the required scope, or the organization's plan does not include API access","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Per-key rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimited"}}}}}}},"/v1/buildings/{id}":{"get":{"tags":["Buildings"],"summary":"Get a single building","security":[{"ApiKey":["buildings:read"]}],"parameters":[{"schema":{"type":"string","description":"Building CUID"},"required":true,"description":"Building CUID","name":"id","in":"path"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildingSingle"}}}},"401":{"description":"Missing, invalid, deactivated or expired API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"API key lacks the required scope, or the organization's plan does not include API access","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Resource not found or not in the calling key's organization","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Per-key rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimited"}}}}}}},"/v1/buildings/{id}/units":{"get":{"tags":["Buildings"],"summary":"List units of a building","description":"Units (fracções) ordered by number, up to 500.","security":[{"ApiKey":["buildings:read"]}],"parameters":[{"schema":{"type":"string","description":"Building CUID"},"required":true,"description":"Building CUID","name":"id","in":"path"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UnitList"}}}},"401":{"description":"Missing, invalid, deactivated or expired API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"API key lacks the required scope, or the organization's plan does not include API access","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Resource not found or not in the calling key's organization","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Per-key rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimited"}}}}}}},"/v1/buildings/{id}/owners":{"get":{"tags":["Owners"],"summary":"List owners of a building","description":"Current (non-erased) owners with their live ledger balance, up to 500.","security":[{"ApiKey":["owners:read"]}],"parameters":[{"schema":{"type":"string","description":"Building CUID"},"required":true,"description":"Building CUID","name":"id","in":"path"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OwnerList"}}}},"401":{"description":"Missing, invalid, deactivated or expired API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"API key lacks the required scope, or the organization's plan does not include API access","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Resource not found or not in the calling key's organization","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Per-key rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimited"}}}}}}},"/v1/arrears":{"get":{"tags":["Owners"],"summary":"Debtors in arrears per building, with aging","description":"Every active building of the organization (or one building with ?buildingId=, whatever its status) with the owners past its arrears threshold, computed from the FinancialDocument ledger with credits applied in settlement order. A building without debtors is returned with an empty list.","security":[{"ApiKey":["owners:read"]}],"parameters":[{"schema":{"type":"string","description":"Restrict to one building"},"required":false,"description":"Restrict to one building","name":"buildingId","in":"query"},{"schema":{"type":"string","description":"Override every building's threshold (0 = every debt already past due); ignored when not a non-negative integer"},"required":false,"description":"Override every building's threshold (0 = every debt already past due); ignored when not a non-negative integer","name":"minMonths","in":"query"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArrearsList"}}}},"401":{"description":"Missing, invalid, deactivated or expired API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"API key lacks the required scope, or the organization's plan does not include API access","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Per-key rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimited"}}}}}}},"/v1/balances/summary":{"get":{"tags":["Owners"],"summary":"Ledger totals per building","description":"Per-building totals from the FinancialDocument ledger: owners, debtors, amount owed, amount in credit and the subset in arrears, plus the organization totals. Inactive buildings are left out unless named with ?buildingId=.","security":[{"ApiKey":["owners:read"]}],"parameters":[{"schema":{"type":"string","description":"Restrict to one building"},"required":false,"description":"Restrict to one building","name":"buildingId","in":"query"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BalancesSummary"}}}},"401":{"description":"Missing, invalid, deactivated or expired API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"API key lacks the required scope, or the organization's plan does not include API access","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Per-key rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimited"}}}}}}},"/v1/buildings/{id}/payments":{"get":{"tags":["Payments"],"summary":"List receipts of a building for one month","description":"Receipts issued in the given month (defaults to the current month), up to 500.","security":[{"ApiKey":["payments:read"]}],"parameters":[{"schema":{"type":"string","description":"Building CUID"},"required":true,"description":"Building CUID","name":"id","in":"path"},{"schema":{"type":"string","description":"Month 1-12; defaults to the current month"},"required":false,"description":"Month 1-12; defaults to the current month","name":"month","in":"query"},{"schema":{"type":"string","description":"Four-digit year; defaults to the current year"},"required":false,"description":"Four-digit year; defaults to the current year","name":"year","in":"query"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaymentList"}}}},"401":{"description":"Missing, invalid, deactivated or expired API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"API key lacks the required scope, or the organization's plan does not include API access","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Resource not found or not in the calling key's organization","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Per-key rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimited"}}}}}}},"/v1/buildings/{id}/expenses":{"get":{"tags":["Expenses"],"summary":"List expenses of a building","description":"Supplier invoices and payments, newest first, up to 500.","security":[{"ApiKey":["expenses:read"]}],"parameters":[{"schema":{"type":"string","description":"Building CUID"},"required":true,"description":"Building CUID","name":"id","in":"path"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExpenseList"}}}},"401":{"description":"Missing, invalid, deactivated or expired API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"API key lacks the required scope, or the organization's plan does not include API access","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Resource not found or not in the calling key's organization","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Per-key rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimited"}}}}}}},"/v1/buildings/{id}/issues":{"get":{"tags":["Issues"],"summary":"List issues of a building","description":"Maintenance issues, newest first, up to 200.","security":[{"ApiKey":["buildings:read"]}],"parameters":[{"schema":{"type":"string","description":"Building CUID"},"required":true,"description":"Building CUID","name":"id","in":"path"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IssueList"}}}},"401":{"description":"Missing, invalid, deactivated or expired API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"API key lacks the required scope, or the organization's plan does not include API access","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Resource not found or not in the calling key's organization","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Per-key rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimited"}}}}}}},"/v1/buildings/{id}/financial-documents":{"get":{"tags":["Financial documents"],"summary":"List ledger documents of a building","description":"The FinancialDocument ledger is the single source of truth for every cent. Cursor-paginated, newest first; filter by type, status and issue date.","security":[{"ApiKey":["financialDocuments:read"]}],"parameters":[{"schema":{"type":"string","description":"Building CUID"},"required":true,"description":"Building CUID","name":"id","in":"path"},{"schema":{"type":"string","description":"Document type, e.g. charge or receipt"},"required":false,"description":"Document type, e.g. charge or receipt","name":"type","in":"query"},{"schema":{"type":"string","description":"Document status, e.g. active or cancelled"},"required":false,"description":"Document status, e.g. active or cancelled","name":"status","in":"query"},{"schema":{"type":"string","description":"Inclusive lower bound on issuedAt (ISO date); ignored when unparsable"},"required":false,"description":"Inclusive lower bound on issuedAt (ISO date); ignored when unparsable","name":"from","in":"query"},{"schema":{"type":"string","description":"Exclusive upper bound on issuedAt (ISO date); ignored when unparsable"},"required":false,"description":"Exclusive upper bound on issuedAt (ISO date); ignored when unparsable","name":"to","in":"query"},{"schema":{"type":"string","description":"Page size, clamped to [1, 200]; default 50"},"required":false,"description":"Page size, clamped to [1, 200]; default 50","name":"limit","in":"query"},{"schema":{"type":"string","description":"`nextCursor` from the previous page"},"required":false,"description":"`nextCursor` from the previous page","name":"cursor","in":"query"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FinancialDocumentList"}}}},"401":{"description":"Missing, invalid, deactivated or expired API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"API key lacks the required scope, or the organization's plan does not include API access","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Resource not found or not in the calling key's organization","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Per-key rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimited"}}}}}}},"/v1/financial-documents/{id}":{"get":{"tags":["Financial documents"],"summary":"Get one ledger document with its reconciliation graph","security":[{"ApiKey":["financialDocuments:read"]}],"parameters":[{"schema":{"type":"string","description":"FinancialDocument CUID"},"required":true,"description":"FinancialDocument CUID","name":"id","in":"path"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FinancialDocumentSingle"}}}},"401":{"description":"Missing, invalid, deactivated or expired API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"API key lacks the required scope, or the organization's plan does not include API access","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Resource not found or not in the calling key's organization","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Per-key rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimited"}}}}}}},"/v1/buildings/{id}/document-links":{"get":{"tags":["Financial documents"],"summary":"List reconciliation links of a building","description":"Every DocumentLink whose source document belongs to the building. Cursor-paginated, newest first.","security":[{"ApiKey":["documentLinks:read"]}],"parameters":[{"schema":{"type":"string","description":"Building CUID"},"required":true,"description":"Building CUID","name":"id","in":"path"},{"schema":{"type":"string","description":"Page size, clamped to [1, 200]; default 50"},"required":false,"description":"Page size, clamped to [1, 200]; default 50","name":"limit","in":"query"},{"schema":{"type":"string","description":"`nextCursor` from the previous page"},"required":false,"description":"`nextCursor` from the previous page","name":"cursor","in":"query"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DocumentLinkList"}}}},"401":{"description":"Missing, invalid, deactivated or expired API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"API key lacks the required scope, or the organization's plan does not include API access","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Resource not found or not in the calling key's organization","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Per-key rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimited"}}}}}}},"/v1/docs":{"get":{"tags":["Meta"],"summary":"Describe the API","description":"Machine-readable summary of the endpoints and scopes. The full OpenAPI document is served at /api/docs/openapi.json without authentication.","security":[{"ApiKey":[]}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiDescription"}}}},"401":{"description":"Missing, invalid, deactivated or expired API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"API key lacks the required scope, or the organization's plan does not include API access","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Per-key rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimited"}}}}}}}}}