# Vespy API — endpoint reference > Vespy API contracts for auth, accounts, dashboard, portfolio, properties, tenants, and leases. Version: 0.1.0 Operations: 317 Servers: - https://api.getvespy.com (Production) - https://api-dev.getvespy.com (Development) - http://localhost:4400 (Local) Every operation below is listed as: METHOD /path [operationId] summary auth: whether a bearer token is required params: path, query, and header parameters body: request body fields returns: status codes and their response shape docs: the human-readable page for this operation Nested objects collapse to `object`. Fetch the complete JSON Schema for any operation from https://docs.getvespy.com/openapi.json. ## Accounting General ledger transactions, groups, and category rollups. GET /api/accounting/category-rollups [get-api-accounting-category-rollups] List accounting category rollups (deprecated) auth: Bearer token required param: startDate (query, required) string param: endDate (query, required) string param: basis (query, optional) "accrual" | "cash" param: propertyId (query, optional) string param: unitId (query, optional) string returns: 200 { rollups: object[] } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-accounting-category-rollups/ GET /api/accounting/journal-entries [get-api-accounting-journal-entries] List manual journal entries auth: Bearer token required returns: 200 { journalEntries: object[] } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-accounting-journal-entries/ POST /api/accounting/journal-entries [post-api-accounting-journal-entries] Create manual journal entry auth: Bearer token required body: { lines: object[]; memo: string; occurredAt: string; status?: "draft" | "posted" } returns: 201 { journalEntry: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 409 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/post-api-accounting-journal-entries/ POST /api/accounting/journal-entries/{id}/post [post-api-accounting-journal-entries-by-id-post] Post draft manual journal entry auth: Bearer token required param: id (path, required) string body: { lines?: object[] } returns: 200 { journalEntry: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } returns: 409 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/post-api-accounting-journal-entries-by-id-post/ POST /api/accounting/journal-entries/{id}/reverse [post-api-accounting-journal-entries-by-id-reverse] Reverse manual journal entry auth: Bearer token required param: id (path, required) string body: { reversalDate?: string } returns: 201 { journalEntry: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } returns: 409 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/post-api-accounting-journal-entries-by-id-reverse/ GET /api/accounting/periods [get-api-accounting-periods] List accounting periods auth: Bearer token required returns: 200 { periods: object[] } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-accounting-periods/ POST /api/accounting/periods/{id}/close [post-api-accounting-periods-by-id-close] Close accounting period auth: Bearer token required param: id (path, required) string returns: 200 { period: object; preCloseChecks: object } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } returns: 409 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/post-api-accounting-periods-by-id-close/ GET /api/accounting/periods/{id}/pre-close-checks [get-api-accounting-periods-by-id-pre-close-checks] Get accounting period pre-close checks auth: Bearer token required param: id (path, required) string returns: 200 { draftJournalsCount: integer; pendingApprovalsCount: integer; unappliedReceivedPaymentsCount: integer; unreconciledBankItemsCount: integer } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } returns: 409 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-accounting-periods-by-id-pre-close-checks/ POST /api/accounting/periods/{id}/reopen [post-api-accounting-periods-by-id-reopen] Reopen accounting period auth: Bearer token required param: id (path, required) string body: { reason: string } returns: 200 { closedAt: string | null; closedByUserId: string | null; createdAt: string; endDate: string; fiscalYear: integer; id: string; organizationId: string; periodNumber: integer; reopenReason: string | null; reopenedAt: string | null; reopenedByUserId: string | null; startDate: string; status: "open" | "soft_closed" | "closed" | "reopened"; updatedAt: string } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/post-api-accounting-periods-by-id-reopen/ POST /api/accounting/periods/{id}/soft-close [post-api-accounting-periods-by-id-soft-close] Soft close accounting period auth: Bearer token required param: id (path, required) string returns: 200 { closedAt: string | null; closedByUserId: string | null; createdAt: string; endDate: string; fiscalYear: integer; id: string; organizationId: string; periodNumber: integer; reopenReason: string | null; reopenedAt: string | null; reopenedByUserId: string | null; startDate: string; status: "open" | "soft_closed" | "closed" | "reopened"; updatedAt: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } returns: 409 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/post-api-accounting-periods-by-id-soft-close/ GET /api/accounting/transaction-groups [get-api-accounting-transaction-groups] List grouped accounting activity auth: Bearer token required param: bookType (query, optional) "trust" | "security_deposit" | "operating" param: categoryId (query, optional) string param: accountId (query, optional) string param: includeDescendants (query, optional) boolean param: propertyId (query, optional) string param: unitId (query, optional) string param: ownerId (query, optional) string param: referenceType (query, optional) "security_deposit" | "disposition" | "charge" | "payment" | "expense" | "expense_payment" | "journal_entry" param: referenceId (query, optional) string param: basis (query, optional) "accrual" | "cash" param: startDate (query, optional) string param: endDate (query, optional) string param: entryType (query, optional) "deposit_received" | "deposit_returned" | "deposit_deducted" | "deposit_forfeited" | "charge_posted" | "charge_voided" | "payment_received" | "payment_reversed" | "expense_recorded" | "expense_paid" | "expense_payment_voided" | "expense_voided" | "adjustment" param: page (query, optional) integer param: pageSize (query, optional) integer returns: 200 { page: integer; pageSize: integer; summary: object; total: integer; totalPages: integer; transactionGroups: object[] } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-accounting-transaction-groups/ GET /api/accounting/transactions [get-api-accounting-transactions] List unified accounting transactions auth: Bearer token required param: bookType (query, optional) "trust" | "security_deposit" | "operating" param: categoryId (query, optional) string param: accountId (query, optional) string param: includeDescendants (query, optional) boolean param: propertyId (query, optional) string param: unitId (query, optional) string param: ownerId (query, optional) string param: referenceType (query, optional) "security_deposit" | "disposition" | "charge" | "payment" | "expense" | "expense_payment" | "journal_entry" param: referenceId (query, optional) string param: basis (query, optional) "accrual" | "cash" param: startDate (query, optional) string param: endDate (query, optional) string param: entryType (query, optional) "deposit_received" | "deposit_returned" | "deposit_deducted" | "deposit_forfeited" | "charge_posted" | "charge_voided" | "payment_received" | "payment_reversed" | "expense_recorded" | "expense_paid" | "expense_payment_voided" | "expense_voided" | "adjustment" param: page (query, optional) integer param: pageSize (query, optional) integer returns: 200 { page: integer; pageSize: integer; total: integer; totalPages: integer; transactions: object[] } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-accounting-transactions/ GET /api/accounting/trial-balance [get-api-accounting-trial-balance] Get trial balance auth: Bearer token required param: asOf (query, required) string param: basis (query, optional) "accrual" | "cash" returns: 200 { asOf: string; basis: "accrual" | "cash"; creditTotalCents: integer; debitTotalCents: integer; isBalanced: boolean; rows: object[] } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-accounting-trial-balance/ ## Accounts Organization profile and staff user administration. GET /api/accounts/organization [get-api-accounts-organization] Get current organization auth: Bearer token required returns: 200 { organization: object } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-accounts-organization/ PUT /api/accounts/organization [put-api-accounts-organization] Update current organization auth: Bearer token required body: unknown | unknown | unknown returns: 200 { organization: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } returns: 409 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/put-api-accounts-organization/ GET /api/accounts/users [get-api-accounts-users] List users in current organization auth: Bearer token required param: search (query, optional) string param: role (query, optional) "admin" | "manager" | "staff" | "tenant" | "owner" param: includeInactive (query, optional) boolean returns: 200 { users: object[] } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-accounts-users/ POST /api/accounts/users [post-api-accounts-users] Create user in current organization auth: Bearer token required body: { email: string; fullName: string; isActive?: boolean; password: string; phone?: string | null; role: "admin" | "manager" | "staff" | "tenant" | "owner" | "vendor" } returns: 201 { user: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 409 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/post-api-accounts-users/ DELETE /api/accounts/users/{id} [delete-api-accounts-users-by-id] Soft-delete user in current organization auth: Bearer token required param: id (path, required) string returns: 204 (no body) returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/delete-api-accounts-users-by-id/ GET /api/accounts/users/{id} [get-api-accounts-users-by-id] Get user in current organization auth: Bearer token required param: id (path, required) string returns: 200 { user: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-accounts-users-by-id/ PUT /api/accounts/users/{id} [put-api-accounts-users-by-id] Update user in current organization auth: Bearer token required param: id (path, required) string body: unknown | unknown | unknown | unknown | unknown | unknown returns: 200 { user: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } returns: 409 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/put-api-accounts-users-by-id/ ## Analytics Time-series portfolio metrics returned as summary plus points. GET /api/analytics/days-vacant [get-api-analytics-days-vacant] Average days vacant between tenancies, and the rent it cost auth: Bearer token required returns: 200 { points: object[]; summary: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-analytics-days-vacant/ GET /api/analytics/delinquency-rate [get-api-analytics-delinquency-rate] Monthly delinquency rate by tenants and by rent past due auth: Bearer token required returns: 200 { points: object[]; summary: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-analytics-delinquency-rate/ GET /api/analytics/economic-occupancy [get-api-analytics-economic-occupancy] Monthly economic occupancy against gross potential rent auth: Bearer token required returns: 200 { points: object[]; summary: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-analytics-economic-occupancy/ GET /api/analytics/lease-expirations [get-api-analytics-lease-expirations] Forward-looking lease expiration schedule auth: Bearer token required returns: 200 { points: object[]; summary: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-analytics-lease-expirations/ GET /api/analytics/move-outs [get-api-analytics-move-outs] Move-outs per month (realized turnover) auth: Bearer token required returns: 200 { points: object[]; summary: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-analytics-move-outs/ GET /api/analytics/net-operating-income [get-api-analytics-net-operating-income] Monthly net operating income (operating income minus operating expenses) auth: Bearer token required returns: 200 { points: object[]; summary: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-analytics-net-operating-income/ GET /api/analytics/new-leases [get-api-analytics-new-leases] New leases and move-ins per month auth: Bearer token required returns: 200 { points: object[]; summary: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-analytics-new-leases/ GET /api/analytics/occupancy-rate [get-api-analytics-occupancy-rate] Monthly physical occupancy rate time-series auth: Bearer token required returns: 200 { points: object[]; summary: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-analytics-occupancy-rate/ GET /api/analytics/operating-expense-ratio [get-api-analytics-operating-expense-ratio] Monthly operating expense ratio auth: Bearer token required returns: 200 { points: object[]; summary: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-analytics-operating-expense-ratio/ GET /api/analytics/operating-expenses-by-category [get-api-analytics-operating-expenses-by-category] Monthly operating expenses broken out by category auth: Bearer token required returns: 200 { categories: object[]; points: object[]; summary: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-analytics-operating-expenses-by-category/ GET /api/analytics/outstanding-ar [get-api-analytics-outstanding-ar] Outstanding receivables at each month end, split into aging bands auth: Bearer token required returns: 200 { points: object[]; summary: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-analytics-outstanding-ar/ GET /api/analytics/renewal-rate [get-api-analytics-renewal-rate] Monthly lease renewal rate auth: Bearer token required returns: 200 { points: object[]; summary: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-analytics-renewal-rate/ GET /api/analytics/rent-owed-vs-collected [get-api-analytics-rent-owed-vs-collected] Monthly rent owed vs rent collected time-series auth: Bearer token required returns: 200 { points: object[]; summary: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-analytics-rent-owed-vs-collected/ GET /api/analytics/work-order-throughput [get-api-analytics-work-order-throughput] Work orders created and completed per month, with average resolution time auth: Bearer token required returns: 200 { points: object[]; summary: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-analytics-work-order-throughput/ ## Auth Login, token refresh, logout, and the current-user profile. POST /api/auth/login [post-api-auth-login] Login auth: none body: { email: string; password: string } returns: 200 { accessToken: string; expiresIn: integer; tokenType: "Bearer"; user: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/post-api-auth-login/ POST /api/auth/logout [post-api-auth-logout] Logout auth: none returns: 200 (no body) docs: https://docs.getvespy.com/api/operations/post-api-auth-logout/ GET /api/auth/me [get-api-auth-me] Get current user auth: Bearer token required returns: 200 { user: object } returns: 401 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-auth-me/ PATCH /api/auth/me/email-consent [patch-api-auth-me-email-consent] Update current user email notification consent auth: Bearer token required body: { emailConsent: boolean } returns: 200 { user: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/patch-api-auth-me-email-consent/ PATCH /api/auth/me/phone [patch-api-auth-me-phone] Update current user notification phone auth: Bearer token required body: { phone: string | null; smsConsent?: boolean } returns: 200 { user: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/patch-api-auth-me-phone/ POST /api/auth/onboarding/complete [post-api-auth-onboarding-complete] Mark onboarding as complete auth: Bearer token required returns: 200 { completedAt: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/post-api-auth-onboarding-complete/ POST /api/auth/token [post-api-auth-token] Refresh access token auth: none body: unknown | unknown returns: 200 { accessToken: string; expiresIn: integer; tokenType: "Bearer"; user: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/post-api-auth-token/ ## Budgets Per-property budgets by category and period. GET /api/budgets [get-api-budgets] List budgets auth: Bearer token required returns: 200 object returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-budgets/ POST /api/budgets [post-api-budgets] Create or update budget auth: Bearer token required returns: 201 object returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/post-api-budgets/ PATCH /api/budgets/{id} [patch-api-budgets-by-id] Patch budget auth: Bearer token required param: id (path, required) string returns: 200 object returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/patch-api-budgets-by-id/ ## Bulk Imports Single-resource CSV template download, validation, and import. GET /api/imports [get-api-imports] List bulk imports auth: Bearer token required returns: 200 { imports: object[] } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-imports/ POST /api/imports [post-api-imports] Upload and validate a bulk import CSV auth: Bearer token required returns: 202 { import: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 503 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/post-api-imports/ GET /api/imports/{id} [get-api-imports-by-id] Get a bulk import auth: Bearer token required param: id (path, required) string returns: 200 { import: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-imports-by-id/ GET /api/imports/{id}/failures.csv [get-api-imports-by-id-failures-csv] Download bulk import failures auth: Bearer token required param: id (path, required) string returns: 200 string returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-imports-by-id-failures-csv/ GET /api/imports/{id}/results [get-api-imports-by-id-results] List bulk import row results auth: Bearer token required param: page (query, optional) integer param: pageSize (query, optional) integer param: failuresOnly (query, optional) boolean param: id (path, required) string returns: 200 { page: integer; pageSize: integer; results: object[]; total: integer; totalPages: integer } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-imports-by-id-results/ POST /api/imports/{id}/start [post-api-imports-by-id-start] Start a validated bulk import auth: Bearer token required param: id (path, required) string returns: 202 { import: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } returns: 409 { code?: string; errors?: object[]; message: string } returns: 503 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/post-api-imports-by-id-start/ GET /api/imports/export/{resourceType} [get-api-imports-export-by-resource-type] Export resources as CSV auth: Bearer token required param: resourceType (path, required) "property" | "unit" | "owner" | "tenant" | "lease" | "vendor" | "charge" | "payment" | "expense" | "expense_payment" returns: 200 string returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-imports-export-by-resource-type/ GET /api/imports/resources [get-api-imports-resources] List bulk import resource definitions auth: Bearer token required returns: 200 { resources: object[] } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-imports-resources/ GET /api/imports/templates/{resourceType} [get-api-imports-templates-by-resource-type] Download a bulk import CSV template auth: Bearer token required param: resourceType (path, required) "property" | "unit" | "owner" | "tenant" | "lease" | "vendor" | "charge" | "payment" | "expense" | "expense_payment" returns: 200 string returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-imports-templates-by-resource-type/ ## Categories System-managed chart of accounts categories. GET /api/categories [get-api-categories] List chart of accounts categories auth: Bearer token required param: type (query, optional) "asset" | "liability" | "equity" | "income" | "cost_of_services" | "expense" | "trust" param: includeInactive (query, optional) boolean param: leafOnly (query, optional) boolean returns: 200 { categories: object[] } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-categories/ DELETE /api/categories/{id} [delete-api-categories-by-id] Categories are system-managed auth: Bearer token required param: id (path, required) string returns: 405 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/delete-api-categories-by-id/ PATCH /api/categories/{id} [patch-api-categories-by-id] Categories are system-managed auth: Bearer token required param: id (path, required) string returns: 405 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/patch-api-categories-by-id/ ## Charges Charges billed to a lease or tenant. GET /api/charges [get-api-charges] List charges auth: Bearer token required param: search (query, optional) string param: status (query, optional) "pending" | "posted" | "paid" | "void" param: tenantId (query, optional) string param: propertyId (query, optional) string param: unitId (query, optional) string param: leaseId (query, optional) string param: dueBefore (query, optional) string param: dueAfter (query, optional) string param: createdAfter (query, optional) string param: createdBefore (query, optional) string param: sortBy (query, optional) "dueDate" | "tenantName" | "propertyName" | "unitNumber" | "chargeType" | "amountCents" | "balanceCents" | "status" | "createdAt" param: sortDirection (query, optional) "asc" | "desc" param: page (query, optional) integer param: pageSize (query, optional) integer returns: 200 { charges: object[]; page: integer; pageSize: integer; total: integer; totalPages: integer } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-charges/ POST /api/charges [post-api-charges] Create charge auth: Bearer token required body: { amountCents: integer; categoryId: string; chargeType?: "rent" | "fee" | "deposit" | "adjustment" | "other"; description?: string; dueDate: string; leaseId?: string; name?: string; propertyId?: string; recurrence?: object; tenantId?: string; unitId?: string } returns: 201 { charge: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } returns: 409 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/post-api-charges/ GET /api/charges/{id} [get-api-charges-by-id] Get charge by id auth: Bearer token required param: id (path, required) string returns: 200 { charge: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-charges-by-id/ PUT /api/charges/{id} [put-api-charges-by-id] Update charge auth: Bearer token required param: id (path, required) string body: unknown | unknown | unknown | unknown | unknown returns: 200 { charge: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } returns: 409 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/put-api-charges-by-id/ POST /api/charges/{id}/void [post-api-charges-by-id-void] Void charge auth: Bearer token required param: id (path, required) string returns: 200 { charge: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } returns: 409 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/post-api-charges-by-id-void/ ## Communication Outbound email and SMS, templates, and delivery status. GET /api/settings/email-accounts [get-api-settings-email-accounts] List organization email accounts auth: Bearer token required returns: 200 { accounts?: object[] } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-settings-email-accounts/ POST /api/settings/email-accounts [post-api-settings-email-accounts] Create an organization email account auth: Bearer token required returns: 201 { account: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/post-api-settings-email-accounts/ DELETE /api/settings/email-accounts/{id} [delete-api-settings-email-accounts-by-id] Delete an organization email account auth: Bearer token required param: id (path, required) string returns: 204 (no body) returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/delete-api-settings-email-accounts-by-id/ GET /api/settings/email-accounts/{id} [get-api-settings-email-accounts-by-id] Get an organization email account auth: Bearer token required param: id (path, required) string returns: 200 { account: object } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-settings-email-accounts-by-id/ PUT /api/settings/email-accounts/{id} [put-api-settings-email-accounts-by-id] Update an organization email account auth: Bearer token required param: id (path, required) string returns: 200 { account: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/put-api-settings-email-accounts-by-id/ ## Conversations Threaded staff, tenant, and owner message timelines. GET /api/conversations [get-api-conversations] List conversations for current user auth: Bearer token required param: status (query, optional) "open" | "closed" | "archived" param: search (query, optional) string param: participantType (query, optional) "tenant" | "vendor" param: participantId (query, optional) string param: limit (query, optional) integer param: offset (query, optional) integer returns: 200 { conversations: object[]; total: integer; unreadCount: integer } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-conversations/ POST /api/conversations [post-api-conversations] Create a conversation auth: Bearer token required body: { body: string; channel?: "in_app" | "sms" | "email"; emailSenderSource?: "system" | "integration"; fromAccountId?: string; participantId?: string; participantType?: "tenant" | "vendor"; subject?: string | null; toAddresses?: string[] } returns: 201 { conversation: object; message: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } returns: 502 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/post-api-conversations/ GET /api/conversations/{id} [get-api-conversations-by-id] Get conversation detail auth: Bearer token required param: id (path, required) string returns: 200 { conversation: object; messages: object[] } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-conversations-by-id/ PATCH /api/conversations/{id} [patch-api-conversations-by-id] Update conversation status auth: Bearer token required param: id (path, required) string body: { status: "open" | "closed" | "archived" } returns: 200 { conversation: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/patch-api-conversations-by-id/ POST /api/conversations/{id}/export [post-api-conversations-by-id-export] Export conversation as PDF auth: Bearer token required param: id (path, required) string returns: 200 { expiresAt: string; fileName: string; url: string } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } returns: 500 { code?: string; errors?: object[]; message: string } returns: 503 { code?: string; errors?: object[]; message: string } returns: 504 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/post-api-conversations-by-id-export/ POST /api/conversations/{id}/messages [post-api-conversations-by-id-messages] Send a message in a conversation auth: Bearer token required param: id (path, required) string body: { body: string; channel?: "in_app" | "sms" | "email"; emailSenderSource?: "system" | "integration"; fromAccountId?: string; toAddresses?: string[] } returns: 200 { message: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } returns: 409 { code?: string; errors?: object[]; message: string } returns: 502 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/post-api-conversations-by-id-messages/ POST /api/conversations/{id}/read [post-api-conversations-by-id-read] Mark a conversation as read auth: Bearer token required param: id (path, required) string returns: 200 { conversation: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/post-api-conversations-by-id-read/ GET /api/conversations/participants [get-api-conversations-participants] List conversation participants for staff inbox auth: Bearer token required param: participantType (query, optional) "tenant" | "vendor" param: search (query, optional) string param: limit (query, optional) integer param: offset (query, optional) integer returns: 200 { participants: object[]; total: integer; unreadCount: integer } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-conversations-participants/ POST /api/conversations/participants/{participantType}/{participantId}/messages [post-api-conversations-participants-by-participant-type-by-participant-id-messages] Send a message to a participant auth: Bearer token required param: participantType (path, required) "tenant" | "vendor" param: participantId (path, required) string body: { body: string; channel?: "in_app" | "sms" | "email"; emailSenderSource?: "system" | "integration"; fromAccountId?: string; subject?: string | null; toAddresses?: string[] } returns: 200 { conversation: object; conversationCreated: boolean; message: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } returns: 409 { code?: string; errors?: object[]; message: string } returns: 502 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/post-api-conversations-participants-by-participant-type-by-participant-id-messages/ POST /api/conversations/participants/{participantType}/{participantId}/read [post-api-conversations-participants-by-participant-type-by-participant-id-read] Mark a participant inbox read auth: Bearer token required param: participantType (path, required) "tenant" | "vendor" param: participantId (path, required) string returns: 200 { participant: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/post-api-conversations-participants-by-participant-type-by-participant-id-read/ GET /api/conversations/participants/{participantType}/{participantId}/timeline [get-api-conversations-participants-by-participant-type-by-participant-id-timeline] Get a participant message timeline auth: Bearer token required param: channel (query, optional) "in_app" | "sms" | "email" param: cursor (query, optional) string param: limit (query, optional) integer param: participantType (path, required) "tenant" | "vendor" param: participantId (path, required) string returns: 200 { conversations: object[]; hasMore: boolean; messages: object[]; nextCursor: string | null; participant: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-conversations-participants-by-participant-type-by-participant-id-timeline/ GET /api/conversations/unread-count [get-api-conversations-unread-count] Get unread conversation count for current user auth: Bearer token required returns: 200 { count: integer } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-conversations-unread-count/ GET /api/messages/search [get-api-messages-search] Search messages auth: Bearer token required param: search (query, optional) string param: channel (query, optional) "in_app" | "sms" | "email" param: participantType (query, optional) "tenant" | "vendor" param: from (query, optional) string param: to (query, optional) string param: limit (query, optional) integer param: offset (query, optional) integer returns: 200 { results: object[]; total: integer } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-messages-search/ ## Dashboard Portfolio summary tiles and the recent activity feed. GET /api/dashboard/activity [get-api-dashboard-activity] Get recent activity feed events auth: Bearer token required param: limit (query, optional) integer returns: 200 { events: object[] } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-dashboard-activity/ GET /api/dashboard/summary [get-api-dashboard-summary] Get dashboard summary auth: Bearer token required returns: 200 { actionItems?: object[]; activeLeases: integer; lateRentLeases: integer; leaseExpirations: object; maintenanceKpis?: object; messagingOverview?: object; occupancyRate: number; occupiedUnits: integer; openWorkOrders: integer; pastDueRentLeases?: object[]; properties: object[]; propertyCount: integer; totalTenants: integer; totalUnits: integer; trustSummary?: object; unitStatusBreakdown: object; vendorComplianceSummary?: object } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-dashboard-summary/ ## Documents Document upload, download, and entity attachment. GET /api/documents [get-api-documents] List documents auth: Bearer token required param: entityType (query, optional) "property" | "unit" | "tenant" | "owner" | "payment" | "expense" | "lease" | "vendor" | "work_order" | "charge" | "expense_payment" param: entityId (query, optional) string param: category (query, optional) string param: expiringBefore (query, optional) string returns: 200 { documents: object[] } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-documents/ POST /api/documents [post-api-documents] Upload document auth: Bearer token required returns: 201 { document: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } returns: 413 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/post-api-documents/ DELETE /api/documents/{id} [delete-api-documents-by-id] Soft-delete document by id auth: Bearer token required param: id (path, required) string returns: 204 (no body) returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/delete-api-documents-by-id/ GET /api/documents/{id} [get-api-documents-by-id] Get document by id auth: Bearer token required param: id (path, required) string returns: 200 { document: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-documents-by-id/ PUT /api/documents/{id} [put-api-documents-by-id] Update document metadata auth: Bearer token required param: id (path, required) string body: unknown | unknown | unknown | unknown | unknown returns: 200 { document: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/put-api-documents-by-id/ GET /api/documents/{id}/download [get-api-documents-by-id-download] Download document by id auth: Bearer token required param: id (path, required) string returns: 302 (no body) returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-documents-by-id-download/ GET /api/documents/{id}/download-url [get-api-documents-by-id-download-url] Get signed download URL for document auth: Bearer token required param: id (path, required) string returns: 200 { url: string } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-documents-by-id-download-url/ POST /api/documents/{id}/reanalyze [post-api-documents-by-id-reanalyze] Queue document AI reanalysis auth: Bearer token required param: id (path, required) string returns: 202 { document: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } returns: 409 { code?: string; errors?: object[]; message: string } returns: 429 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/post-api-documents-by-id-reanalyze/ POST /api/documents/check-expiry [post-api-documents-check-expiry] Create document expiry alerts auth: Bearer token required returns: 200 { alerts: integer } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/post-api-documents-check-expiry/ GET /api/documents/entity-options [get-api-documents-entity-options] List document entity options auth: Bearer token required returns: 200 { charge: object[]; expense: object[]; expense_payment: object[]; lease: object[]; owner: object[]; payment: object[]; property: object[]; tenant: object[]; unit: object[]; vendor: object[]; work_order: object[] } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-documents-entity-options/ ## ExpensePayments Payments issued against recorded expenses. GET /api/expense-payments [get-api-expense-payments] List expense payments auth: Bearer token required param: search (query, optional) string param: vendorId (query, optional) string param: expenseId (query, optional) string param: status (query, optional) "issued" | "pending" | "failed" | "voided" param: paidAfter (query, optional) string param: paidBefore (query, optional) string param: createdAfter (query, optional) string param: createdBefore (query, optional) string param: sortBy (query, optional) "paidAt" | "vendorName" | "amountCents" | "paymentMethod" | "status" | "createdAt" param: sortDirection (query, optional) "asc" | "desc" param: page (query, optional) integer param: pageSize (query, optional) integer returns: 200 { expensePayments: object[]; page: integer; pageSize: integer; total: integer; totalPages: integer } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-expense-payments/ POST /api/expense-payments [post-api-expense-payments] Create expense payment auth: Bearer token required body: { allocations: object[]; amountCents: integer; memo?: string; paidAt: string; paymentMethod: "ach" | "card" | "cash" | "check" | "other"; referenceNumber?: string; vendorId?: string } returns: 201 { expensePayment: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } returns: 409 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/post-api-expense-payments/ GET /api/expense-payments/{id} [get-api-expense-payments-by-id] Get expense payment by id auth: Bearer token required param: id (path, required) string returns: 200 { expensePayment: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-expense-payments-by-id/ POST /api/expense-payments/{id}/allocate [post-api-expense-payments-by-id-allocate] Allocate expense payment to expenses auth: Bearer token required param: id (path, required) string body: { allocations: object[] } returns: 200 { expensePayment: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } returns: 409 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/post-api-expense-payments-by-id-allocate/ DELETE /api/expense-payments/{id}/allocations/{allocationId} [delete-api-expense-payments-by-id-allocations-by-allocation-id] Remove expense payment allocation auth: Bearer token required param: id (path, required) string param: allocationId (path, required) string returns: 200 { expensePayment: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/delete-api-expense-payments-by-id-allocations-by-allocation-id/ POST /api/expense-payments/{id}/void [post-api-expense-payments-by-id-void] Void expense payment auth: Bearer token required param: id (path, required) string returns: 200 { expensePayment: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } returns: 409 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/post-api-expense-payments-by-id-void/ ## Expenses Property and unit expenses. GET /api/expenses [get-api-expenses] List expenses auth: Bearer token required param: search (query, optional) string param: propertyId (query, optional) string param: ownerId (query, optional) string param: unitId (query, optional) string param: leaseId (query, optional) string param: vendorId (query, optional) string param: workOrderId (query, optional) string param: category (query, optional) "maintenance" | "utility" | "tax" | "insurance" | "management" | "other" param: status (query, optional) "active" | "voided" param: paymentStatus (query, optional) "pending" | "partial" | "paid" param: incurredAfter (query, optional) string param: incurredBefore (query, optional) string param: createdAfter (query, optional) string param: createdBefore (query, optional) string param: sortBy (query, optional) "incurredOn" | "propertyName" | "unitNumber" | "vendorName" | "category" | "amountCents" | "paymentStatus" | "createdAt" param: sortDirection (query, optional) "asc" | "desc" param: page (query, optional) integer param: pageSize (query, optional) integer returns: 200 { expenses: object[]; page: integer; pageSize: integer; total: integer; totalPages: integer } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-expenses/ POST /api/expenses [post-api-expenses] Create expense auth: Bearer token required body: { amountCents: integer; category?: "maintenance" | "utility" | "tax" | "insurance" | "management" | "other"; categoryId: string; description?: string; incurredOn: string; leaseId?: string; name?: string; ownerId?: string; propertyId: string; unitId?: string; vendorId?: string; vendorName?: string; workOrderId?: string } returns: 201 { expense: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/post-api-expenses/ GET /api/expenses/{id} [get-api-expenses-by-id] Get expense by id auth: Bearer token required param: id (path, required) string returns: 200 { expense: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-expenses-by-id/ PUT /api/expenses/{id} [put-api-expenses-by-id] Update expense auth: Bearer token required param: id (path, required) string body: unknown | unknown | unknown | unknown | unknown | unknown | unknown | unknown | unknown returns: 200 { expense: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } returns: 409 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/put-api-expenses-by-id/ POST /api/expenses/{id}/void [post-api-expenses-by-id-void] Void expense auth: Bearer token required param: id (path, required) string returns: 200 { expense: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } returns: 409 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/post-api-expenses-by-id-void/ ## Import Bundles Multi-resource migration bundles imported as one unit. GET /api/import-bundles [get-api-import-bundles] List import bundles auth: Bearer token required returns: 200 { bundles: object[] } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-import-bundles/ POST /api/import-bundles [post-api-import-bundles] Create an import bundle auth: Bearer token required body: { name: string; provider: "generic" | "appfolio" | "turbotenant"; sourceAccountLabel?: string | null; sourceNamespace: string } returns: 201 { bundle: object; chunks: object[]; files: object[]; imports: object[] } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 409 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/post-api-import-bundles/ GET /api/import-bundles/{id} [get-api-import-bundles-by-id] Get an import bundle auth: Bearer token required param: id (path, required) string returns: 200 { bundle: object; chunks: object[]; files: object[]; imports: object[] } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-import-bundles-by-id/ POST /api/import-bundles/{id}/cancel [post-api-import-bundles-by-id-cancel] Cancel an import bundle auth: Bearer token required param: id (path, required) string returns: 200 { bundle: object; chunks: object[]; files: object[]; imports: object[] } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } returns: 409 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/post-api-import-bundles-by-id-cancel/ GET /api/import-bundles/{id}/candidates [get-api-import-bundles-by-id-candidates] List import bundle candidates auth: Bearer token required param: page (query, optional) integer param: pageSize (query, optional) integer param: status (query, optional) "ready_create" | "ready_update" | "unchanged" | "duplicate_merged" | "ambiguous" | "missing_source_data" | "invalid" | "blocked" | "excluded" | "created" | "updated" | "failed" param: resourceType (query, optional) "property" | "unit" | "owner" | "tenant" | "lease" | "vendor" | "charge" | "payment" | "expense" | "expense_payment" param: id (path, required) string returns: 200 { candidates: object[]; page: integer; pageSize: integer; total: integer; totalPages: integer } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-import-bundles-by-id-candidates/ PATCH /api/import-bundles/{id}/candidates/{candidateId} [patch-api-import-bundles-by-id-candidates-by-candidate-id] Resolve an import bundle candidate auth: Bearer token required param: id (path, required) string param: candidateId (path, required) string body: { action: "edit" | "exclude" | "match"; canonicalPayload?: object; reason: string; resolvedEntityId?: string } returns: 200 { candidates: object[]; page: integer; pageSize: integer; total: integer; totalPages: integer } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/patch-api-import-bundles-by-id-candidates-by-candidate-id/ GET /api/import-bundles/{id}/failures.csv [get-api-import-bundles-by-id-failures-csv] Download bundle failures auth: Bearer token required param: id (path, required) string returns: 200 string returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-import-bundles-by-id-failures-csv/ POST /api/import-bundles/{id}/files [post-api-import-bundles-by-id-files] Upload import bundle CSV files auth: Bearer token required param: id (path, required) string returns: 201 { bundle: object; chunks: object[]; files: object[]; imports: object[] } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } returns: 409 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/post-api-import-bundles-by-id-files/ DELETE /api/import-bundles/{id}/files/{fileId} [delete-api-import-bundles-by-id-files-by-file-id] Delete a draft bundle file auth: Bearer token required param: id (path, required) string param: fileId (path, required) string returns: 204 (no body) returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } returns: 409 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/delete-api-import-bundles-by-id-files-by-file-id/ PATCH /api/import-bundles/{id}/files/{fileId} [patch-api-import-bundles-by-id-files-by-file-id] Update bundle file mapping auth: Bearer token required param: id (path, required) string param: fileId (path, required) string body: { mapping?: object; providerFileKind?: string; transformations?: object } returns: 200 { bundle: object; chunks: object[]; files: object[]; imports: object[] } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } returns: 409 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/patch-api-import-bundles-by-id-files-by-file-id/ GET /api/import-bundles/{id}/identity-map.csv [get-api-import-bundles-by-id-identity-map-csv] Download bundle identity map auth: Bearer token required param: id (path, required) string returns: 200 string returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-import-bundles-by-id-identity-map-csv/ GET /api/import-bundles/{id}/results [get-api-import-bundles-by-id-results] List import bundle results auth: Bearer token required param: page (query, optional) integer param: pageSize (query, optional) integer param: status (query, optional) "ready_create" | "ready_update" | "unchanged" | "duplicate_merged" | "ambiguous" | "missing_source_data" | "invalid" | "blocked" | "excluded" | "created" | "updated" | "failed" param: resourceType (query, optional) "property" | "unit" | "owner" | "tenant" | "lease" | "vendor" | "charge" | "payment" | "expense" | "expense_payment" param: id (path, required) string returns: 200 { candidates: object[]; page: integer; pageSize: integer; total: integer; totalPages: integer } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-import-bundles-by-id-results/ POST /api/import-bundles/{id}/start [post-api-import-bundles-by-id-start] Start an import bundle auth: Bearer token required param: id (path, required) string returns: 202 { bundle: object; chunks: object[]; files: object[]; imports: object[] } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } returns: 409 { code?: string; errors?: object[]; message: string } returns: 503 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/post-api-import-bundles-by-id-start/ POST /api/import-bundles/{id}/validate [post-api-import-bundles-by-id-validate] Validate an import bundle auth: Bearer token required param: id (path, required) string returns: 202 { bundle: object; chunks: object[]; files: object[]; imports: object[] } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } returns: 409 { code?: string; errors?: object[]; message: string } returns: 503 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/post-api-import-bundles-by-id-validate/ GET /api/import-bundles/templates/{provider} [get-api-import-bundles-templates-by-provider] Download all migration bundle templates for a provider auth: Bearer token required param: provider (path, required) "generic" | "appfolio" | "turbotenant" returns: 200 string returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-import-bundles-templates-by-provider/ GET /api/import-mapping-profiles [get-api-import-mapping-profiles] List import mapping profiles auth: Bearer token required returns: 200 { profiles: object[] } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-import-mapping-profiles/ POST /api/import-mapping-profiles [post-api-import-mapping-profiles] Save an import mapping profile auth: Bearer token required body: { adapterVersion: string; fileKind: string; headerFingerprint: string; mapping: object; name: string; provider: "generic" | "appfolio" | "turbotenant"; transformations?: object } returns: 201 { profile: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/post-api-import-mapping-profiles/ DELETE /api/import-mapping-profiles/{id} [delete-api-import-mapping-profiles-by-id] Delete an import mapping profile auth: Bearer token required param: id (path, required) string returns: 204 (no body) returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/delete-api-import-mapping-profiles-by-id/ ## Inspections Move-in, move-out, and periodic lease inspections. GET /api/leases/{id}/inspections [get-api-leases-by-id-inspections] List inspections for a lease auth: Bearer token required param: id (path, required) string returns: 200 { inspections: object[] } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-leases-by-id-inspections/ POST /api/leases/{id}/inspections [post-api-leases-by-id-inspections] Create an inspection for a lease auth: Bearer token required param: id (path, required) string body: { items?: object[]; notes?: string | null; performedAt?: string; type: "move_in" | "move_out" } returns: 201 { inspection: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/post-api-leases-by-id-inspections/ ## Integrations Third-party connections such as Gmail and QuickBooks Online. GET /api/integrations [get-api-integrations] List visible integration connections auth: Bearer token required returns: 200 object returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-integrations/ DELETE /api/integrations/{id} [delete-api-integrations-by-id] Delete a manageable integration connection auth: Bearer token required param: id (path, required) string returns: 204 (no body) returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/delete-api-integrations-by-id/ GET /api/integrations/{id} [get-api-integrations-by-id] Get one visible integration connection auth: Bearer token required param: id (path, required) string returns: 200 object returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-integrations-by-id/ PUT /api/integrations/{id} [put-api-integrations-by-id] Update a manageable integration connection auth: Bearer token required param: id (path, required) string returns: 200 object returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/put-api-integrations-by-id/ GET /api/integrations/catalog [get-api-integrations-catalog] List integration provider definitions auth: Bearer token required returns: 200 object returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-integrations-catalog/ POST /api/integrations/gmail/connect [post-api-integrations-gmail-connect] Begin Gmail OAuth connection auth: Bearer token required returns: 200 { redirectUrl: string } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/post-api-integrations-gmail-connect/ GET /api/integrations/gmail/oauth-callback [get-api-integrations-gmail-oauth-callback] Gmail OAuth redirect target Browser-facing redirect target for the Gmail OAuth consent flow. Not called directly by API clients; always responds with a redirect back to the `returnUrl` carried in the signed `state` parameter. auth: none returns: 302 object returns: 400 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-integrations-gmail-oauth-callback/ GET /api/integrations/gmail/oauth-return [get-api-integrations-gmail-oauth-return] Gmail OAuth redirect target Browser-facing redirect target for the Gmail OAuth consent flow. Not called directly by API clients; always responds with a redirect back to the `returnUrl` carried in the signed `state` parameter. auth: none returns: 302 object returns: 400 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-integrations-gmail-oauth-return/ GET /api/integrations/qbo/accounts [get-api-integrations-qbo-accounts] List QuickBooks Online chart-of-accounts entries for mapping auth: Bearer token required returns: 200 { accounts: object[] } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } returns: 409 { code?: string; errors?: object[]; message: string } returns: 502 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-integrations-qbo-accounts/ POST /api/integrations/qbo/connect [post-api-integrations-qbo-connect] Begin QuickBooks Online OAuth connection auth: Bearer token required returns: 200 { redirectUrl: string } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/post-api-integrations-qbo-connect/ POST /api/integrations/qbo/export [post-api-integrations-qbo-export] Queue an export of Vespy transactions to QuickBooks Online auth: Bearer token required returns: 202 { fromDate: null|string; queued: boolean; toDate: null|string } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } returns: 503 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/post-api-integrations-qbo-export/ GET /api/integrations/qbo/export/records [get-api-integrations-qbo-export-records] List per-transaction QuickBooks export results auth: Bearer token required param: status (query, optional) "pending" | "synced" | "failed" | "skipped" | "conflict" param: page (query, optional) integer param: pageSize (query, optional) integer returns: 200 { page: integer; pageSize: integer; records: object[]; total: integer; totalPages: integer } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-integrations-qbo-export-records/ GET /api/integrations/qbo/export/status [get-api-integrations-qbo-export-status] Get QuickBooks export status for the organization auth: Bearer token required returns: 200 { connected: boolean; connection: null|object; exportFromDate: null|string; exportToDate: null|string; lastRun: null|object; recordCounts: object; requiredMappings: object[] } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-integrations-qbo-export-status/ GET /api/integrations/qbo/mappings [get-api-integrations-qbo-mappings] List QuickBooks account mappings auth: Bearer token required returns: 200 { mappings: object[] } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-integrations-qbo-mappings/ PUT /api/integrations/qbo/mappings [put-api-integrations-qbo-mappings] Replace QuickBooks account mappings auth: Bearer token required returns: 200 { mappings: object[] } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } returns: 409 { code?: string; errors?: object[]; message: string } returns: 502 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/put-api-integrations-qbo-mappings/ POST /api/integrations/qbo/mappings/auto [post-api-integrations-qbo-mappings-auto] Create and save required QuickBooks account mappings auth: Bearer token required returns: 200 { createdAccountCount: integer; mappedCategoryIds: string[]; mappings: object[] } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } returns: 409 { code?: string; errors?: object[]; message: string } returns: 502 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/post-api-integrations-qbo-mappings-auto/ GET /api/integrations/qbo/oauth-callback [get-api-integrations-qbo-oauth-callback] QuickBooks Online OAuth redirect target Browser-facing redirect target for the QuickBooks Online OAuth consent flow. Not called directly by API clients; always responds with a redirect back to the `returnUrl` carried in the signed `state` parameter. auth: none returns: 302 object returns: 400 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-integrations-qbo-oauth-callback/ GET /api/integrations/qbo/oauth-return [get-api-integrations-qbo-oauth-return] QuickBooks Online OAuth redirect target Browser-facing redirect target for the QuickBooks Online OAuth consent flow. Not called directly by API clients; always responds with a redirect back to the `returnUrl` carried in the signed `state` parameter. auth: none returns: 302 object returns: 400 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-integrations-qbo-oauth-return/ ## Leases Lease agreements, terms, renewals, and lifecycle transitions. GET /api/leases [get-api-leases] List leases auth: Bearer token required param: search (query, optional) string param: status (query, optional) "draft" | "active" | "ended" | "terminated" param: propertyId (query, optional) string param: tenantId (query, optional) string param: unitId (query, optional) string param: createdAfter (query, optional) string param: createdBefore (query, optional) string param: expiringAfterDays (query, optional) integer param: expiringWithinDays (query, optional) integer param: minOverdueRentCents (query, optional) integer param: maxOverdueRentCents (query, optional) integer param: sortBy (query, optional) "tenantName" | "propertyName" | "unitNumber" | "startDate" | "endDate" | "rentCents" | "status" | "createdAt" | "overduePostedRentCents" param: sortDirection (query, optional) "asc" | "desc" returns: 200 { leases: object[]; noteSummaries: object[] } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-leases/ POST /api/leases [post-api-leases] Create lease auth: Bearer token required body: { additionalRecurringCharges?: object[]; endDate: string | null; lateFeeAmountCents?: integer | null; lateFeeGraceDays?: integer; lateFeePercentBps?: integer | null; lateFeeType?: "none" | "flat" | "percent"; moveInDate?: string; occupants?: object[]; propertyId: string; rentCents: integer; rentChargeDay?: integer; startDate: string; status?: "draft" | "active" | "ended" | "terminated"; tenantId: string; termType?: "fixed" | "month_to_month"; unitId: string } returns: 201 { lease: object; notes: object[]; recurringChargeRules: object[] } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } returns: 409 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/post-api-leases/ DELETE /api/leases/{id} [delete-api-leases-by-id] Soft-delete lease by id auth: Bearer token required param: id (path, required) string returns: 204 (no body) returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/delete-api-leases-by-id/ GET /api/leases/{id} [get-api-leases-by-id] Get lease by id auth: Bearer token required param: id (path, required) string returns: 200 { lease: object; notes: object[]; recurringChargeRules: object[] } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-leases-by-id/ PUT /api/leases/{id} [put-api-leases-by-id] Update lease details auth: Bearer token required param: id (path, required) string body: unknown | unknown | unknown | unknown | unknown | unknown | unknown | unknown | unknown | unknown | unknown | unknown | unknown | unknown | unknown returns: 200 { lease: object; notes: object[]; recurringChargeRules: object[] } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } returns: 409 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/put-api-leases-by-id/ POST /api/leases/{id}/renew [post-api-leases-by-id-renew] Renew an active lease auth: Bearer token required param: id (path, required) string body: { endDate: string | null; moveInDate?: string; rentCents?: integer; startDate: string; termType?: "fixed" | "month_to_month" } returns: 201 { lease: object; notes: object[]; recurringChargeRules: object[] } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } returns: 409 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/post-api-leases-by-id-renew/ POST /api/leases/{id}/status [post-api-leases-by-id-status] Update lease status auth: Bearer token required param: id (path, required) string body: { status: "draft" | "active" | "ended" | "terminated" } returns: 200 { lease: object; notes: object[]; recurringChargeRules: object[] } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } returns: 409 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/post-api-leases-by-id-status/ POST /api/leases/{id}/terminate [post-api-leases-by-id-terminate] Terminate an active lease early with optional deposit reconciliation auth: Bearer token required param: id (path, required) string body: { depositDeductions?: object[]; prorateRent?: boolean; refundAmountCents?: integer; refundReason?: string; securityDepositId?: string | null; terminationDate: string } returns: 200 { lease: object; notes: object[]; recurringChargeRules: object[] } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/post-api-leases-by-id-terminate/ ## Management Fees Management fee rules and their calculation runs. GET /api/management-fee-rules [get-api-management-fee-rules] List management fee rules auth: Bearer token required param: propertyId (query, optional) string param: ownerId (query, optional) string param: includeEnded (query, optional) boolean returns: 200 { managementFeeRules: object[] } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-management-fee-rules/ POST /api/management-fee-rules [post-api-management-fee-rules] Create a management fee rule auth: Bearer token required body: { feeFlatCents: integer | null; feePercentageBps: integer | null; feeType: "flat" | "percentage" | "hybrid"; generationDayOfMonth: integer; ownerId: string; propertyId: string; rentBasisShareBps: integer | null } returns: 201 { managementFeeRule: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } returns: 409 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/post-api-management-fee-rules/ DELETE /api/management-fee-rules/{id} [delete-api-management-fee-rules-by-id] End or cancel a management fee rule auth: Bearer token required param: id (path, required) string returns: 204 (no body) returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/delete-api-management-fee-rules-by-id/ PATCH /api/management-fee-rules/{id} [patch-api-management-fee-rules-by-id] Revise a management fee rule for a future period auth: Bearer token required param: id (path, required) string body: { feeFlatCents?: integer | null; feePercentageBps?: integer | null; feeType?: "flat" | "percentage" | "hybrid"; generationDayOfMonth?: integer; rentBasisShareBps?: integer | null } returns: 200 { managementFeeRule: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } returns: 409 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/patch-api-management-fee-rules-by-id/ GET /api/management-fee-runs [get-api-management-fee-runs] List management fee calculation runs auth: Bearer token required param: ruleId (query, optional) string param: propertyId (query, optional) string param: ownerId (query, optional) string returns: 200 { managementFeeRuns: object[] } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-management-fee-runs/ ## Notes Free-form notes attached to portfolio entities. GET /api/notes [get-api-notes] List notes attached to an entity auth: Bearer token required param: entityType (query, required) "property" | "unit" | "owner" | "tenant" | "lease" | "vendor" | "work_order" param: entityId (query, required) string returns: 200 { notes: object[] } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-notes/ POST /api/notes [post-api-notes] Create a note on an entity auth: Bearer token required body: { body: string; entityId: string; entityType: "property" | "unit" | "owner" | "tenant" | "lease" | "vendor" | "work_order"; visibility: "organization_only" | "tenant_shared" | "vendor_shared" | "tenant_vendor_shared" } returns: 201 { note: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/post-api-notes/ DELETE /api/notes/{id} [delete-api-notes-by-id] Delete a note auth: Bearer token required param: id (path, required) string returns: 204 (no body) returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/delete-api-notes-by-id/ PUT /api/notes/{id} [put-api-notes-by-id] Update a note body or visibility auth: Bearer token required param: id (path, required) string body: { body: string; visibility: "organization_only" | "tenant_shared" | "vendor_shared" | "tenant_vendor_shared" } returns: 200 { note: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/put-api-notes-by-id/ ## Notifications In-app notifications and per-family delivery preferences. GET /api/notification-preferences [get-api-notification-preferences] Get grouped notification preferences for the current user auth: Bearer token required returns: 200 { preferences: object[] } returns: 401 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-notification-preferences/ PATCH /api/notification-preferences [patch-api-notification-preferences] Update grouped notification preferences for the current user auth: Bearer token required body: { preferences: unknown | unknown | unknown | unknown[] } returns: 200 { preferences: object[] } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/patch-api-notification-preferences/ GET /api/notifications [get-api-notifications] List notifications for current user auth: Bearer token required param: unreadOnly (query, optional) boolean param: channel (query, optional) "in_app" | "email" | "sms" | "push" param: limit (query, optional) integer param: offset (query, optional) integer returns: 200 { notifications: object[]; total: integer; unreadCount: integer } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-notifications/ GET /api/notifications/{id} [get-api-notifications-by-id] Get a notification with its per-channel deliveries auth: Bearer token required param: id (path, required) string returns: 200 { deliveries: object[]; notification: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-notifications-by-id/ POST /api/notifications/{id}/read [post-api-notifications-by-id-read] Mark a notification as read auth: Bearer token required param: id (path, required) string returns: 200 { notification: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/post-api-notifications-by-id-read/ POST /api/notifications/blasts/{id}/send [post-api-notifications-blasts-by-id-send] Queue an approved notification blast auth: Bearer token required param: id (path, required) string returns: 200 { blast: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } returns: 503 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/post-api-notifications-blasts-by-id-send/ POST /api/notifications/blasts/preview [post-api-notifications-blasts-preview] Preview a custom notification blast auth: Bearer token required body: { autoTranslate?: boolean; body: string; channels: "in_app" | "email" | "sms"[]; target: unknown | unknown | unknown; title: string } returns: 201 { blast: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/post-api-notifications-blasts-preview/ GET /api/notifications/digest-preview [get-api-notifications-digest-preview] Preview the pending digest email for the current admin user auth: Bearer token required returns: 200 { preview: object } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-notifications-digest-preview/ POST /api/notifications/digest-send-now [post-api-notifications-digest-send-now] Send the pending digest email immediately for the current admin user auth: Bearer token required returns: 200 { error: string | null; messageId: string | null; notificationCount: integer; provider: string | null; status: "sent" | "skipped" | "failed" } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/post-api-notifications-digest-send-now/ GET /api/notifications/history [get-api-notifications-history] List organization notification delivery history auth: Bearer token required param: search (query, optional) string param: recipientType (query, optional) "user" | "tenant" param: recipientId (query, optional) string param: channel (query, optional) "in_app" | "email" | "sms" | "push" param: limit (query, optional) integer param: offset (query, optional) integer returns: 200 { items: object[]; total: integer } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-notifications-history/ GET /api/notifications/history/{source}/{id} [get-api-notifications-history-by-source-by-id] Get an organization notification history item auth: Bearer token required param: source (path, required) "notification" | "blast_recipient" param: id (path, required) string returns: 200 { item: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-notifications-history-by-source-by-id/ GET /api/notifications/history/recipients [get-api-notifications-history-recipients] List notification history recipient filter options auth: Bearer token required param: search (query, optional) string param: limit (query, optional) integer returns: 200 { recipients: object[] } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-notifications-history-recipients/ POST /api/notifications/mark-all-read [post-api-notifications-mark-all-read] Mark all notifications as read for current user auth: Bearer token required returns: 200 { updated: integer } returns: 401 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/post-api-notifications-mark-all-read/ POST /api/notifications/mark-read [post-api-notifications-mark-read] Mark selected notifications as read for current user auth: Bearer token required body: { ids: string[] } returns: 200 { updated: integer } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/post-api-notifications-mark-read/ POST /api/notifications/test [post-api-notifications-test] Send a test notification to the current user on a single channel auth: Bearer token required body: { channel: "in_app" | "email" | "sms" } returns: 200 { channel: "in_app" | "email" | "sms"; error: string | null; messageId: string | null; provider: string | null; status: "sent" | "skipped" | "error" } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/post-api-notifications-test/ GET /api/notifications/unread-count [get-api-notifications-unread-count] Get unread notification count for current user auth: Bearer token required returns: 200 { count: integer } returns: 401 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-notifications-unread-count/ GET /api/settings/notification-settings [get-api-settings-notification-settings] Get organization notification settings auth: Bearer token required returns: 200 { settings: object } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-settings-notification-settings/ PATCH /api/settings/notification-settings [patch-api-settings-notification-settings] Update organization notification settings auth: Bearer token required body: { rentReminders: unknown | unknown | unknown | unknown } returns: 200 { settings: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/patch-api-settings-notification-settings/ ## Online Payments Stripe-backed payment methods, autopay, and Connect onboarding. POST /api/payments/connect/refresh-link [post-api-payments-connect-refresh-link] Issue a fresh Stripe Connect onboarding link auth: Bearer token required returns: 200 { accountId: string; url: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 409 { code?: string; errors?: object[]; message: string } returns: 502 { code?: string; errors?: object[]; message: string } returns: 503 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/post-api-payments-connect-refresh-link/ POST /api/payments/connect/start [post-api-payments-connect-start] Start or resume Stripe Connect onboarding auth: Bearer token required returns: 200 { accountId: string; url: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 502 { code?: string; errors?: object[]; message: string } returns: 503 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/post-api-payments-connect-start/ GET /api/payments/connect/status [get-api-payments-connect-status] Get Stripe Connect onboarding status auth: Bearer token required returns: 200 { status: object } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 502 { code?: string; errors?: object[]; message: string } returns: 503 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-payments-connect-status/ DELETE /api/portal/autopay [delete-api-portal-autopay] Cancel autopay for the authenticated tenant auth: Bearer token required returns: 204 (no body) returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } returns: 503 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/delete-api-portal-autopay/ GET /api/portal/autopay [get-api-portal-autopay] Get the autopay schedule for the authenticated tenant auth: Bearer token required returns: 200 { autopay: object } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 503 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-portal-autopay/ PATCH /api/portal/autopay [patch-api-portal-autopay] Update the autopay payment method or status auth: Bearer token required body: { paymentMethodId?: string; status?: "active" | "paused" } returns: 200 { autopay: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } returns: 503 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/patch-api-portal-autopay/ POST /api/portal/autopay [post-api-portal-autopay] Enroll the authenticated tenant in autopay auth: Bearer token required body: { authorizationLanguageVersion: string; leaseId: string; paymentMethodId: string } returns: 201 { autopay: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } returns: 409 { code?: string; errors?: object[]; message: string } returns: 503 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/post-api-portal-autopay/ GET /api/portal/payment-methods [get-api-portal-payment-methods] List saved payment methods for the authenticated tenant auth: Bearer token required returns: 200 { paymentMethods: object[] } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 503 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-portal-payment-methods/ POST /api/portal/payment-methods [post-api-portal-payment-methods] Save a payment method from a completed setup intent auth: Bearer token required body: { authorizationKind?: "one_time" | "recurring"; authorizationLanguageVersion?: string; isDefault?: boolean; setupIntentId: string } returns: 201 { paymentMethod: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 409 { code?: string; errors?: object[]; message: string } returns: 412 { code?: string; errors?: object[]; message: string } returns: 503 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/post-api-portal-payment-methods/ DELETE /api/portal/payment-methods/{id} [delete-api-portal-payment-methods-by-id] Remove a saved payment method auth: Bearer token required param: id (path, required) string returns: 204 (no body) returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } returns: 409 { code?: string; errors?: object[]; message: string } returns: 503 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/delete-api-portal-payment-methods-by-id/ POST /api/portal/payment-methods/setup-intent [post-api-portal-payment-methods-setup-intent] Create a Stripe setup intent for a new payment method auth: Bearer token required returns: 200 { clientSecret: string; connectedAccountId: string; setupIntentId: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 412 { code?: string; errors?: object[]; message: string } returns: 503 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/post-api-portal-payment-methods-setup-intent/ POST /api/portal/payments [post-api-portal-payments] Create a payment intent for selected charges auth: Bearer token required body: { authorizationLanguageVersion?: string; chargeIds: string[]; paymentMethodId: string } returns: 200 { amountCents: integer; clientSecret: string; connectedAccountId: string; convenienceFeeCents: integer; paymentId: string } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 409 { code?: string; errors?: object[]; message: string } returns: 412 { code?: string; errors?: object[]; message: string } returns: 503 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/post-api-portal-payments/ GET /api/portal/payments/charges [get-api-portal-payments-charges] List charges the authenticated tenant can pay auth: Bearer token required returns: 200 { charges: object[] } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 503 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-portal-payments-charges/ POST /api/staff/billing/checkout-session [post-api-staff-billing-checkout-session] Create a Stripe Checkout session for the platform subscription auth: Bearer token required returns: 200 { url: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } returns: 503 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/post-api-staff-billing-checkout-session/ POST /api/staff/billing/portal-session [post-api-staff-billing-portal-session] Create a Stripe billing portal session auth: Bearer token required returns: 200 { url: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 409 { code?: string; errors?: object[]; message: string } returns: 503 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/post-api-staff-billing-portal-session/ GET /api/staff/billing/status [get-api-staff-billing-status] Get the organization platform billing status auth: Bearer token required returns: 200 { billing: object } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 503 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-staff-billing-status/ ## Owners Property owners, their statements, and owner ledgers. GET /api/owners [get-api-owners] List owners auth: Bearer token required param: search (query, optional) string param: includeInactive (query, optional) boolean param: createdAfter (query, optional) string param: createdBefore (query, optional) string param: sortBy (query, optional) "fullName" | "email" | "isActive" | "createdAt" param: sortDirection (query, optional) "asc" | "desc" returns: 200 { noteSummaries: object[]; owners: object[] } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-owners/ POST /api/owners [post-api-owners] Create owner auth: Bearer token required body: { email: string; fullName: string; isActive?: boolean; phone?: string | null } returns: 201 { notes: object[]; owner: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 409 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/post-api-owners/ DELETE /api/owners/{id} [delete-api-owners-by-id] Soft-delete owner by id auth: Bearer token required param: id (path, required) string returns: 204 (no body) returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/delete-api-owners-by-id/ GET /api/owners/{id} [get-api-owners-by-id] Get owner by id auth: Bearer token required param: id (path, required) string returns: 200 { notes: object[]; owner: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-owners-by-id/ PUT /api/owners/{id} [put-api-owners-by-id] Update owner by id auth: Bearer token required param: id (path, required) string body: unknown | unknown | unknown | unknown returns: 200 { notes: object[]; owner: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } returns: 409 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/put-api-owners-by-id/ GET /api/owners/{id}/ledger [get-api-owners-by-id-ledger] Get owner ledger auth: Bearer token required param: startDate (query, optional) string param: endDate (query, optional) string param: id (path, required) string returns: 200 { closingBalanceCents: integer; openingBalanceCents: integer; summary: object; transactions: object[] } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-owners-by-id-ledger/ ## Payments Payments received and their allocation to charges. GET /api/payments [get-api-payments] List payments auth: Bearer token required param: search (query, optional) string param: tenantId (query, optional) string param: leaseId (query, optional) string param: propertyId (query, optional) string param: unitId (query, optional) string param: status (query, optional) "received" | "pending" | "failed" | "reversed" param: receivedAfter (query, optional) string param: receivedBefore (query, optional) string param: createdAfter (query, optional) string param: createdBefore (query, optional) string param: sortBy (query, optional) "receivedAt" | "tenantName" | "propertyName" | "amountCents" | "paymentMethod" | "allocatedCents" | "unallocatedCents" | "status" | "createdAt" param: sortDirection (query, optional) "asc" | "desc" param: page (query, optional) integer param: pageSize (query, optional) integer returns: 200 { page: integer; pageSize: integer; payments: object[]; total: integer; totalPages: integer } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-payments/ POST /api/payments [post-api-payments] Create payment auth: Bearer token required body: { allocations?: object[]; amountCents: integer; checkNumber?: string; idempotencyKey: string; leaseId?: string; paymentMethod: "ach" | "card" | "cash" | "check" | "other"; receivedAt: string; tenantId: string } returns: 201 { payment: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } returns: 409 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/post-api-payments/ GET /api/payments/{id} [get-api-payments-by-id] Get payment by id auth: Bearer token required param: id (path, required) string returns: 200 { payment: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-payments-by-id/ PUT /api/payments/{id} [put-api-payments-by-id] Reject payment updates auth: Bearer token required param: id (path, required) string returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 409 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/put-api-payments-by-id/ POST /api/payments/{id}/allocate [post-api-payments-by-id-allocate] Allocate payment to charges auth: Bearer token required param: id (path, required) string body: { allocations: object[] } returns: 200 { payment: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } returns: 409 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/post-api-payments-by-id-allocate/ DELETE /api/payments/{id}/allocations/{allocationId} [delete-api-payments-by-id-allocations-by-allocation-id] Remove payment allocation auth: Bearer token required param: id (path, required) string param: allocationId (path, required) string returns: 200 { payment: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/delete-api-payments-by-id-allocations-by-allocation-id/ PUT /api/payments/{id}/allocations/{allocationId} [put-api-payments-by-id-allocations-by-allocation-id] Update payment allocation auth: Bearer token required param: id (path, required) string param: allocationId (path, required) string body: { amountCents: integer } returns: 200 { payment: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } returns: 409 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/put-api-payments-by-id-allocations-by-allocation-id/ POST /api/payments/{id}/reverse [post-api-payments-by-id-reverse] Reverse payment auth: Bearer token required param: id (path, required) string returns: 200 { payment: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } returns: 409 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/post-api-payments-by-id-reverse/ POST /api/payments/{id}/transition [post-api-payments-by-id-transition] Transition a pending payment auth: Bearer token required param: id (path, required) string body: { status: "received" | "failed" } returns: 200 { payment: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } returns: 409 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/post-api-payments-by-id-transition/ ## Portal Endpoints scoped to an authenticated tenant or owner. GET /api/owner/ledger [get-api-owner-ledger] Get the authenticated owner ledger auth: Bearer token required param: startDate (query, optional) string param: endDate (query, optional) string returns: 200 { closingBalanceCents: integer; openingBalanceCents: integer; summary: object; transactions: object[] } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-owner-ledger/ GET /api/tenant/dashboard [get-api-tenant-dashboard] Get tenant portal dashboard auth: Bearer token required returns: 200 { currentBalanceCents: integer; currentMonthLedger: object; lease: object; nextRentAmountCents: integer | null; nextRentDueDate: string | null; recentMaintenance: object[]; recentNotifications: object[]; tenant: object } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-tenant-dashboard/ GET /api/tenant/documents [get-api-tenant-documents] List tenant and lease documents for the authenticated tenant auth: Bearer token required returns: 200 { documents: object[] } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-tenant-documents/ GET /api/tenant/documents/{id}/download-url [get-api-tenant-documents-by-id-download-url] Get a signed download URL for an accessible tenant portal document auth: Bearer token required param: id (path, required) string returns: 200 { url: string } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-tenant-documents-by-id-download-url/ GET /api/tenant/lease [get-api-tenant-lease] Get the current or most recent lease for the authenticated tenant auth: Bearer token required returns: 200 { documents: object[]; lease: object } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-tenant-lease/ GET /api/tenant/ledger [get-api-tenant-ledger] Get the tenant ledger for the current month auth: Bearer token required returns: 200 { closingBalanceCents: integer; openingBalanceCents: integer; summary: object; transactions: object[] } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-tenant-ledger/ GET /api/tenant/maintenance [get-api-tenant-maintenance] List maintenance requests for the authenticated tenant auth: Bearer token required param: category (query, optional) "plumbing" | "electrical" | "hvac" | "appliance" | "structural" | "pest_control" | "landscaping" | "general" | "other" returns: 200 { workOrders: object[] } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-tenant-maintenance/ POST /api/tenant/maintenance [post-api-tenant-maintenance] Create a maintenance request for the authenticated tenant auth: Bearer token required body: { category?: "plumbing" | "electrical" | "hvac" | "appliance" | "structural" | "pest_control" | "landscaping" | "general" | "other"; description?: string; entryInstructions?: string; priority?: "low" | "normal" | "high" | "emergency"; title: string } returns: 201 { workOrder: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/post-api-tenant-maintenance/ GET /api/tenant/maintenance/{id} [get-api-tenant-maintenance-by-id] Get a maintenance request for the authenticated tenant auth: Bearer token required param: id (path, required) string returns: 200 { attachmentCount: integer; attachments: object[]; linkedExpenses: object[]; notes: object[]; workOrder: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-tenant-maintenance-by-id/ POST /api/tenant/maintenance/{id}/attachments [post-api-tenant-maintenance-by-id-attachments] Upload an attachment for a tenant maintenance request auth: Bearer token required param: id (path, required) string returns: 201 { document: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } returns: 413 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/post-api-tenant-maintenance-by-id-attachments/ POST /api/tenant/maintenance/{id}/comments [post-api-tenant-maintenance-by-id-comments] Add a tenant-visible comment to a maintenance request auth: Bearer token required param: id (path, required) string body: { body: string } returns: 201 { note: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/post-api-tenant-maintenance-by-id-comments/ ## Properties Properties and their addresses, ownership, and settings. GET /api/properties [get-api-properties] List properties auth: Bearer token required param: search (query, optional) string param: createdAfter (query, optional) string param: createdBefore (query, optional) string param: minOccupancyRate (query, optional) integer param: maxOccupancyRate (query, optional) integer param: sortBy (query, optional) "name" | "city" | "units" | "occupiedUnits" | "occupancyRate" | "overduePostedRentCents" | "openWorkOrderCount" | "createdAt" param: sortDirection (query, optional) "asc" | "desc" returns: 200 { noteSummaries: object[]; properties: object[] } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-properties/ POST /api/properties [post-api-properties] Create property auth: Bearer token required body: { city: string; initialUnit?: object; name: string; occupiedUnits: integer; ownerIds?: string[]; postalCode: string; state: string; streetLine1: string; streetLine2?: string | null; units: integer } returns: 201 { notes: object[]; property: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 409 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/post-api-properties/ DELETE /api/properties/{id} [delete-api-properties-by-id] Delete property auth: Bearer token required param: id (path, required) string returns: 204 (no body) returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } returns: 409 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/delete-api-properties-by-id/ GET /api/properties/{id} [get-api-properties-by-id] Get property by id auth: Bearer token required param: id (path, required) string returns: 200 { notes: object[]; property: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-properties-by-id/ PUT /api/properties/{id} [put-api-properties-by-id] Update property auth: Bearer token required param: id (path, required) string body: { city: string; name: string; occupiedUnits: integer; ownerIds?: string[]; postalCode: string; state: string; streetLine1: string; streetLine2?: string | null; units: integer } returns: 200 { notes: object[]; property: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } returns: 409 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/put-api-properties-by-id/ GET /api/properties/{id}/leases [get-api-properties-by-id-leases] List leases for a property auth: Bearer token required param: id (path, required) string returns: 200 { leases: object[]; noteSummaries: object[] } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-properties-by-id-leases/ GET /api/properties/{propertyId}/units [get-api-properties-by-property-id-units] List units for a property auth: Bearer token required param: propertyId (path, required) string returns: 200 { units: object[] } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-properties-by-property-id-units/ POST /api/properties/{propertyId}/units [post-api-properties-by-property-id-units] Create unit for a property auth: Bearer token required param: propertyId (path, required) string body: { accessInstructions?: string; bathrooms: integer; bedrooms: integer; currentLease?: object; currentTenant?: object; description?: string; feeTemplates?: object[]; monthlyRentCents: integer; status: "occupied" | "vacant" | "maintenance"; unitNumber?: string | null } returns: 201 { feeTemplates: object[]; unit: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } returns: 409 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/post-api-properties-by-property-id-units/ DELETE /api/properties/{propertyId}/units/{unitId} [delete-api-properties-by-property-id-units-by-unit-id] Delete unit for a property auth: Bearer token required param: propertyId (path, required) string param: unitId (path, required) string returns: 204 (no body) returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/delete-api-properties-by-property-id-units-by-unit-id/ GET /api/properties/{propertyId}/units/{unitId} [get-api-properties-by-property-id-units-by-unit-id] Get unit by id for a property auth: Bearer token required param: propertyId (path, required) string param: unitId (path, required) string returns: 200 { feeTemplates: object[]; unit: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-properties-by-property-id-units-by-unit-id/ PUT /api/properties/{propertyId}/units/{unitId} [put-api-properties-by-property-id-units-by-unit-id] Update unit for a property auth: Bearer token required param: propertyId (path, required) string param: unitId (path, required) string body: { accessInstructions?: string; bathrooms: integer; bedrooms: integer; description?: string; monthlyRentCents: integer; status: "occupied" | "vacant" | "maintenance"; unitNumber?: string | null } returns: 200 { feeTemplates: object[]; unit: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } returns: 409 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/put-api-properties-by-property-id-units-by-unit-id/ ## Recurring Charges Charge schedules that generate charges on a cadence. GET /api/recurring-charges [get-api-recurring-charges] List recurring charge rules auth: Bearer token required param: leaseId (query, optional) string param: unitId (query, optional) string param: kind (query, optional) "rent" | "fee" returns: 200 { recurringChargeRules: object[] } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-recurring-charges/ POST /api/recurring-charges [post-api-recurring-charges] Create recurring charge rule auth: Bearer token required body: { amountCents: integer; categoryId: string; label: string; leaseId?: string; propertyId?: string; recurrence: object; tenantId?: string; unitId?: string } returns: 201 { charge: object; recurringChargeRule: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/post-api-recurring-charges/ DELETE /api/recurring-charges/{id} [delete-api-recurring-charges-by-id] Delete recurring charge rule auth: Bearer token required param: id (path, required) string returns: 204 (no body) returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/delete-api-recurring-charges-by-id/ GET /api/recurring-charges/{id} [get-api-recurring-charges-by-id] Get recurring charge rule by id auth: Bearer token required param: id (path, required) string returns: 200 { recurringChargeRule: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-recurring-charges-by-id/ PATCH /api/recurring-charges/{id} [patch-api-recurring-charges-by-id] Update recurring charge rule auth: Bearer token required param: id (path, required) string body: unknown | unknown | unknown | unknown | unknown | unknown returns: 200 { recurringChargeRule: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/patch-api-recurring-charges-by-id/ POST /api/recurring-charges/{id}/pause [post-api-recurring-charges-by-id-pause] Pause recurring charge rule auth: Bearer token required param: id (path, required) string returns: 200 { recurringChargeRule: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/post-api-recurring-charges-by-id-pause/ POST /api/recurring-charges/{id}/resume [post-api-recurring-charges-by-id-resume] Resume recurring charge rule auth: Bearer token required param: id (path, required) string returns: 200 { recurringChargeRule: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/post-api-recurring-charges-by-id-resume/ ## Reports Generated financial and operational reports, including exports. GET /api/reports/balance-sheet [get-api-reports-balance-sheet] Get balance sheet report auth: Bearer token required returns: 200 object returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 501 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-reports-balance-sheet/ GET /api/reports/budget-vs-actual [get-api-reports-budget-vs-actual] Get budget vs actual report auth: Bearer token required returns: 200 object returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 501 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-reports-budget-vs-actual/ GET /api/reports/cash-flow [get-api-reports-cash-flow] Get cash flow report auth: Bearer token required returns: 200 object returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 501 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-reports-cash-flow/ GET /api/reports/delinquency [get-api-reports-delinquency] Get delinquency report auth: Bearer token required returns: 200 object returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 501 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-reports-delinquency/ GET /api/reports/general-ledger [get-api-reports-general-ledger] Get general ledger report auth: Bearer token required returns: 200 object returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 501 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-reports-general-ledger/ GET /api/reports/gpr-egi [get-api-reports-gpr-egi] Get GPR vs EGI report auth: Bearer token required returns: 200 object returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 501 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-reports-gpr-egi/ GET /api/reports/lease-expirations [get-api-reports-lease-expirations] Get lease expirations report auth: Bearer token required returns: 200 object returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 501 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-reports-lease-expirations/ GET /api/reports/maintenance-costs [get-api-reports-maintenance-costs] Get maintenance costs report auth: Bearer token required returns: 200 object returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 501 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-reports-maintenance-costs/ GET /api/reports/profit-and-loss [get-api-reports-profit-and-loss] Get profit and loss report auth: Bearer token required returns: 200 object returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 501 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-reports-profit-and-loss/ GET /api/reports/rent-roll [get-api-reports-rent-roll] Get rent roll report auth: Bearer token required returns: 200 object returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 501 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-reports-rent-roll/ GET /api/reports/security-deposit-ledger [get-api-reports-security-deposit-ledger] Get security deposit ledger report auth: Bearer token required returns: 200 object returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 501 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-reports-security-deposit-ledger/ POST /api/reports/snapshots [post-api-reports-snapshots] Create report snapshot auth: Bearer token required returns: 201 object returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/post-api-reports-snapshots/ GET /api/reports/transactions [get-api-reports-transactions] List report drill-down transactions auth: Bearer token required returns: 200 object returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-reports-transactions/ ## Search Federated search across portfolio entities and index maintenance. GET /api/search [get-api-search] Run federated search across portfolio entities auth: Bearer token required param: q (query, required) string param: types (query, optional) string param: limit (query, optional) integer returns: 200 { query: string; results: object[]; totalHits: integer } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-search/ POST /api/search/reindex [post-api-search-reindex] Refresh global search index auth: Bearer token required returns: 200 { success: true } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/post-api-search-reindex/ ## Short Links Short URL redirects for links delivered over SMS. GET /s/{code} [get-s-by-code] Follow a short link Redirects to the link target. Unknown, expired, and revoked codes all redirect to the onboarding page instead. auth: none param: code (path, required) string returns: 302 object returns: 429 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-s-by-code/ ## System Health checks and build metadata. GET /health [get-health] Health check auth: none returns: 200 { status: "ok" } docs: https://docs.getvespy.com/api/operations/get-health/ GET /version [get-version] API build version auth: none returns: 200 { buildDate: string; commit: string } docs: https://docs.getvespy.com/api/operations/get-version/ ## Tenant Invites Invitations that let a tenant claim a portal login. GET /api/tenant-invites [get-api-tenant-invites] List tenant invites auth: Bearer token required param: tenantId (query, optional) string param: status (query, optional) "pending" | "accepted" | "expired" returns: 200 { invites: object[] } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-tenant-invites/ POST /api/tenant-invites [post-api-tenant-invites] Create and send tenant invite auth: Bearer token required body: { channels: "email" | "sms"[]; email?: string; leaseId?: string | null; phone?: string; tenantId: string } returns: 201 { emailDelivery: object; invite: object; inviteLink: string; shortInviteLink: string | null; smsDelivery: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } returns: 409 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/post-api-tenant-invites/ POST /api/tenant-invites/{id}/revoke [post-api-tenant-invites-by-id-revoke] Revoke tenant invite auth: Bearer token required param: id (path, required) string returns: 200 { invite: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/post-api-tenant-invites-by-id-revoke/ GET /api/tenant-invites/{token} [get-api-tenant-invites-by-token] Validate tenant invite token auth: none param: token (path, required) string returns: 200 { invite: object; lease: object; tenant: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-tenant-invites-by-token/ POST /api/tenant-invites/{token}/accept [post-api-tenant-invites-by-token-accept] Accept tenant invite auth: none param: token (path, required) string body: { password: string } returns: 200 { accessToken: string; expiresIn: integer; tokenType: "Bearer"; user: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } returns: 409 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/post-api-tenant-invites-by-token-accept/ ## Tenants Tenant records and their lease associations. GET /api/tenants [get-api-tenants] List tenants auth: Bearer token required param: search (query, optional) string param: includeInactive (query, optional) boolean param: propertyId (query, optional) string param: unitId (query, optional) string param: createdAfter (query, optional) string param: createdBefore (query, optional) string param: sortBy (query, optional) "fullName" | "email" | "isActive" | "createdAt" param: sortDirection (query, optional) "asc" | "desc" returns: 200 { noteSummaries: object[]; tenants: object[] } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-tenants/ POST /api/tenants [post-api-tenants] Create tenant auth: Bearer token required body: { email: string; emergencyContactName?: string | null; emergencyContactPhone?: string | null; emergencyContactRelationship?: string | null; fullName: string; isActive?: boolean; phone?: string | null; preferredLanguage?: string; userId?: string | null } returns: 201 { notes: object[]; tenant: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } returns: 409 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/post-api-tenants/ DELETE /api/tenants/{id} [delete-api-tenants-by-id] Soft-delete tenant by id auth: Bearer token required param: id (path, required) string returns: 204 (no body) returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/delete-api-tenants-by-id/ GET /api/tenants/{id} [get-api-tenants-by-id] Get tenant by id auth: Bearer token required param: id (path, required) string returns: 200 { notes: object[]; tenant: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-tenants-by-id/ PUT /api/tenants/{id} [put-api-tenants-by-id] Update tenant by id auth: Bearer token required param: id (path, required) string body: unknown | unknown | unknown | unknown | unknown | unknown | unknown | unknown | unknown returns: 200 { notes: object[]; tenant: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } returns: 409 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/put-api-tenants-by-id/ GET /api/tenants/{id}/ledger [get-api-tenants-by-id-ledger] Get tenant ledger auth: Bearer token required param: startDate (query, optional) string param: endDate (query, optional) string param: id (path, required) string returns: 200 { closingBalanceCents: integer; openingBalanceCents: integer; summary: object; transactions: object[] } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-tenants-by-id-ledger/ ## Trust Trust bank accounts, reconciliation, and owner payables. GET /api/trust/bank-accounts [get-api-trust-bank-accounts] List trust bank accounts auth: Bearer token required param: ownerId (query, optional) string param: accountType (query, optional) "operating" | "security_deposit" | "trust" | "other" param: isActive (query, optional) boolean returns: 200 { bankAccounts: object[] } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-trust-bank-accounts/ POST /api/trust/bank-accounts [post-api-trust-bank-accounts] Create trust bank account auth: Bearer token required body: { accountMask?: string; accountType?: "operating" | "security_deposit" | "trust" | "other"; institutionName?: string; isActive?: boolean; name: string; ownerId?: string } returns: 201 { bankAccount: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/post-api-trust-bank-accounts/ DELETE /api/trust/bank-accounts/{id} [delete-api-trust-bank-accounts-by-id] Archive trust bank account auth: Bearer token required param: id (path, required) string returns: 200 { bankAccount: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } returns: 409 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/delete-api-trust-bank-accounts-by-id/ PATCH /api/trust/bank-accounts/{id} [patch-api-trust-bank-accounts-by-id] Update trust bank account auth: Bearer token required param: id (path, required) string body: { accountMask?: string | null; accountType?: "operating" | "security_deposit" | "trust" | "other"; institutionName?: string | null; isActive?: boolean; name?: string; ownerId?: string | null } returns: 200 { bankAccount: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/patch-api-trust-bank-accounts-by-id/ GET /api/trust/deposits [get-api-trust-deposits] List security deposits auth: Bearer token required param: leaseId (query, optional) string param: tenantId (query, optional) string param: bankAccountId (query, optional) string param: status (query, optional) "held" | "partially_returned" | "returned" | "forfeited" param: isOverdue (query, optional) boolean returns: 200 { securityDeposits: object[] } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-trust-deposits/ POST /api/trust/deposits [post-api-trust-deposits] Record security deposit auth: Bearer token required body: { amountCents: integer; bankAccountId?: string; leaseId?: string; receivedAt?: string; status?: "held" | "partially_returned" | "returned" | "forfeited"; tenantId?: string } returns: 201 { securityDeposit: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } returns: 409 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/post-api-trust-deposits/ GET /api/trust/deposits/{id} [get-api-trust-deposits-by-id] Get security deposit detail auth: Bearer token required param: id (path, required) string returns: 200 { dispositions: object[]; securityDeposit: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-trust-deposits-by-id/ GET /api/trust/deposits/{id}/deduction-statement [get-api-trust-deposits-by-id-deduction-statement] Download itemized deduction statement auth: Bearer token required param: id (path, required) string returns: 200 string returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-trust-deposits-by-id-deduction-statement/ POST /api/trust/deposits/{id}/dispositions [post-api-trust-deposits-by-id-dispositions] Record security deposit disposition auth: Bearer token required param: id (path, required) string body: { amountCents: integer; documentId?: string; lineItems?: object[]; reason: string; type: "deduction" | "refund" } returns: 201 { disposition: object; securityDeposit: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } returns: 409 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/post-api-trust-deposits-by-id-dispositions/ GET /api/trust/ledger [get-api-trust-ledger] List trust ledger entries auth: Bearer token required param: bankAccountId (query, optional) string param: book (query, optional) "trust" | "security_deposit" | "operating" param: entryType (query, optional) "deposit_received" | "deposit_returned" | "deposit_deducted" | "deposit_forfeited" | "charge_posted" | "charge_voided" | "payment_received" | "payment_reversed" | "expense_recorded" | "expense_paid" | "expense_payment_voided" | "expense_voided" | "adjustment" param: categoryId (query, optional) string param: startDate (query, optional) string param: endDate (query, optional) string param: limit (query, optional) integer param: offset (query, optional) integer returns: 200 { ledgerEntries: object[] } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-trust-ledger/ GET /api/trust/owner-payables [get-api-trust-owner-payables] List owner payables auth: Bearer token required param: ownerId (query, optional) string param: status (query, optional) "pending" | "paid" | "voided" returns: 200 { ownerPayables: object[] } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-trust-owner-payables/ POST /api/trust/owner-payables [post-api-trust-owner-payables] Create owner payable auth: Bearer token required body: { amountCents: integer; description?: string; ownerId: string; propertyId?: string } returns: 201 { ownerPayable: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/post-api-trust-owner-payables/ POST /api/trust/owner-payables/{id}/pay [post-api-trust-owner-payables-by-id-pay] Mark owner payable paid auth: Bearer token required param: id (path, required) string returns: 200 { ownerPayable: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } returns: 409 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/post-api-trust-owner-payables-by-id-pay/ POST /api/trust/owner-payables/{id}/void [post-api-trust-owner-payables-by-id-void] Void owner payable auth: Bearer token required param: id (path, required) string returns: 200 { ownerPayable: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } returns: 409 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/post-api-trust-owner-payables-by-id-void/ GET /api/trust/reconciliations [get-api-trust-reconciliations] List trust reconciliations auth: Bearer token required param: bankAccountId (query, optional) string param: periodStart (query, optional) string param: periodEnd (query, optional) string returns: 200 { reconciliations: object[] } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-trust-reconciliations/ POST /api/trust/reconciliations [post-api-trust-reconciliations] Run trust reconciliation auth: Bearer token required body: { bankAccountId: string; bookBalanceCents?: integer; ledgerEndingBalanceCents?: integer; periodEnd: string; periodStart: string; reconciliationType?: "manual" | "automated"; statementEndingBalanceCents: integer; subledgerTotalCents?: integer; unresolvedItems?: object[] } returns: 201 { trustReconciliation: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/post-api-trust-reconciliations/ GET /api/trust/reconciliations/{id} [get-api-trust-reconciliations-by-id] Get trust reconciliation auth: Bearer token required param: id (path, required) string returns: 200 { trustReconciliation: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-trust-reconciliations-by-id/ GET /api/trust/subledger-balances [get-api-trust-subledger-balances] List owner subledger balances auth: Bearer token required param: bankAccountId (query, required) string returns: 200 { subledgerBalances: object[] } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-trust-subledger-balances/ ## Units Rentable units belonging to a property. GET /api/units [get-api-units] List units across the authenticated organization auth: Bearer token required param: search (query, optional) string param: status (query, optional) "occupied" | "vacant" | "maintenance" param: propertyId (query, optional) string param: createdAfter (query, optional) string param: createdBefore (query, optional) string param: minOverdueRentCents (query, optional) integer param: maxOverdueRentCents (query, optional) integer param: minOpenWorkOrders (query, optional) integer param: maxOpenWorkOrders (query, optional) integer param: sortBy (query, optional) "unitNumber" | "propertyName" | "bedrooms" | "bathrooms" | "monthlyRentCents" | "status" | "createdAt" | "overduePostedRentCents" | "openWorkOrderCount" param: sortDirection (query, optional) "asc" | "desc" returns: 200 { noteSummaries: object[]; units: object[] } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-units/ POST /api/units [post-api-units] Create a unit auth: Bearer token required body: { accessInstructions?: string; bathrooms: integer; bedrooms: integer; description?: string; feeTemplates?: object[]; monthlyRentCents: integer; propertyId: string; status: "occupied" | "vacant" | "maintenance"; unitNumber?: string | null } returns: 201 { feeTemplates: object[]; notes: object[]; unit: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } returns: 409 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/post-api-units/ DELETE /api/units/{id} [delete-api-units-by-id] Delete a unit auth: Bearer token required param: id (path, required) string returns: 204 (no body) returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/delete-api-units-by-id/ GET /api/units/{id} [get-api-units-by-id] Get unit by id auth: Bearer token required param: id (path, required) string returns: 200 { feeTemplates: object[]; notes: object[]; unit: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-units-by-id/ PUT /api/units/{id} [put-api-units-by-id] Update a unit auth: Bearer token required param: id (path, required) string body: { accessInstructions?: string; bathrooms: integer; bedrooms: integer; description?: string; monthlyRentCents: integer; propertyId: string; status: "occupied" | "vacant" | "maintenance"; unitNumber?: string | null } returns: 200 { feeTemplates: object[]; notes: object[]; unit: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } returns: 409 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/put-api-units-by-id/ GET /api/units/{id}/leases [get-api-units-by-id-leases] List leases for a unit auth: Bearer token required param: id (path, required) string returns: 200 { leases: object[]; noteSummaries: object[] } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-units-by-id-leases/ GET /api/units/{unitId}/fees [get-api-units-by-unit-id-fees] List unit fee templates auth: Bearer token required param: unitId (path, required) string returns: 200 { feeTemplates: object[] } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-units-by-unit-id-fees/ POST /api/units/{unitId}/fees [post-api-units-by-unit-id-fees] Create unit fee template auth: Bearer token required param: unitId (path, required) string body: { amountCents: integer; categoryId: string; defaultDueDay?: integer | null; label: string } returns: 201 { feeTemplate: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/post-api-units-by-unit-id-fees/ DELETE /api/units/{unitId}/fees/{feeId} [delete-api-units-by-unit-id-fees-by-fee-id] Delete unit fee template auth: Bearer token required param: unitId (path, required) string param: feeId (path, required) string returns: 204 (no body) returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/delete-api-units-by-unit-id-fees-by-fee-id/ PATCH /api/units/{unitId}/fees/{feeId} [patch-api-units-by-unit-id-fees-by-fee-id] Update unit fee template auth: Bearer token required param: unitId (path, required) string param: feeId (path, required) string body: unknown | unknown | unknown | unknown returns: 200 { feeTemplate: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/patch-api-units-by-unit-id-fees-by-fee-id/ ## Vendor Invites Invitations that let a vendor claim a portal login. GET /api/vendor-invites [get-api-vendor-invites] List vendor invites auth: Bearer token required returns: 200 { invites: object[] } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-vendor-invites/ POST /api/vendor-invites [post-api-vendor-invites] Create and send vendor invite auth: Bearer token required returns: 201 { emailDelivery: object; invite: object; inviteLink: string } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/post-api-vendor-invites/ POST /api/vendor-invites/{id}/revoke [post-api-vendor-invites-by-id-revoke] Revoke vendor invite auth: Bearer token required param: id (path, required) string returns: 200 { invite: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/post-api-vendor-invites-by-id-revoke/ GET /api/vendor-invites/{token} [get-api-vendor-invites-by-token] Validate vendor invite token auth: none param: token (path, required) string returns: 200 { invite: object; vendor: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-vendor-invites-by-token/ POST /api/vendor-invites/{token}/accept [post-api-vendor-invites-by-token-accept] Accept vendor invite auth: none param: token (path, required) string returns: 200 { accessToken: string; expiresIn: integer; tokenType: "Bearer"; user: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } returns: 409 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/post-api-vendor-invites-by-token-accept/ ## Vendor Portal Endpoints scoped to an authenticated vendor. GET /api/vendor/dashboard [get-api-vendor-dashboard] Get vendor portal dashboard auth: Bearer token required returns: 200 { assignedWorkOrders: object[]; complianceSummary: object; recentNotifications: object[]; vendor: object } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-vendor-dashboard/ GET /api/vendor/documents [get-api-vendor-documents] List vendor compliance documents auth: Bearer token required returns: 200 { complianceSummary: object; documents: object[] } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-vendor-documents/ POST /api/vendor/documents [post-api-vendor-documents] Upload a vendor compliance document auth: Bearer token required returns: 201 { document: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/post-api-vendor-documents/ GET /api/vendor/documents/{id}/download-url [get-api-vendor-documents-by-id-download-url] Get signed download URL for vendor document auth: Bearer token required param: id (path, required) string returns: 200 { url: string } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-vendor-documents-by-id-download-url/ GET /api/vendor/work-orders [get-api-vendor-work-orders] List work orders assigned to vendor auth: Bearer token required param: status (query, optional) "open" | "in_progress" | "completed" | "cancelled" param: category (query, optional) "plumbing" | "electrical" | "hvac" | "appliance" | "structural" | "pest_control" | "landscaping" | "general" | "other" returns: 200 { workOrders: object[] } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-vendor-work-orders/ GET /api/vendor/work-orders/{id} [get-api-vendor-work-orders-by-id] Get work order detail for vendor auth: Bearer token required param: id (path, required) string returns: 200 { attachments: object[]; notes: object[]; workOrder: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-vendor-work-orders-by-id/ POST /api/vendor/work-orders/{id}/comments [post-api-vendor-work-orders-by-id-comments] Add a comment to a work order auth: Bearer token required param: id (path, required) string returns: 201 { note: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/post-api-vendor-work-orders-by-id-comments/ ## Vendors Vendor directory used for work orders and expenses. GET /api/vendors [get-api-vendors] List vendors with note and compliance summaries auth: Bearer token required param: trade (query, optional) string param: isActive (query, optional) boolean param: search (query, optional) string param: createdAfter (query, optional) string param: createdBefore (query, optional) string param: complianceStatus (query, optional) "compliant" | "warning" | "missing" | "expired" param: sortBy (query, optional) "name" | "trade" | "isActive" | "createdAt" param: sortDirection (query, optional) "asc" | "desc" returns: 200 { complianceSummaries: object[]; noteSummaries: object[]; vendors: object[] } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-vendors/ POST /api/vendors [post-api-vendors] Create a vendor auth: Bearer token required body: { email?: string | null; isActive?: boolean; name: string; phone?: string | null; trade?: string | null } returns: 201 { vendor: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/post-api-vendors/ DELETE /api/vendors/{id} [delete-api-vendors-by-id] Soft-delete a vendor auth: Bearer token required param: id (path, required) string returns: 204 (no body) returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/delete-api-vendors-by-id/ GET /api/vendors/{id} [get-api-vendors-by-id] Get a vendor with work orders, expenses, and compliance auth: Bearer token required param: id (path, required) string returns: 200 { activeWorkOrders: object[]; complianceDocuments: object[]; complianceSummary: object; notes: object[]; recentExpenses: object[]; recentlyCompletedWorkOrders: object[]; vendor: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-vendors-by-id/ PUT /api/vendors/{id} [put-api-vendors-by-id] Update a vendor auth: Bearer token required param: id (path, required) string body: { email?: string | null; isActive?: boolean; name?: string; phone?: string | null; trade?: string | null } returns: 200 { vendor: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/put-api-vendors-by-id/ ## Work Orders Maintenance work orders, assignment, and status changes. GET /api/work-orders [get-api-work-orders] List work orders with note summaries auth: Bearer token required param: status (query, optional) "open" | "in_progress" | "completed" | "cancelled" param: priority (query, optional) "low" | "normal" | "high" | "emergency" param: category (query, optional) "plumbing" | "electrical" | "hvac" | "appliance" | "structural" | "pest_control" | "landscaping" | "general" | "other" param: propertyId (query, optional) string param: unitId (query, optional) string param: vendorId (query, optional) string param: assignedStaffUserId (query, optional) string param: source (query, optional) "staff" | "tenant" param: createdAfter (query, optional) string param: createdBefore (query, optional) string param: sortBy (query, optional) "title" | "status" | "priority" | "source" | "createdAt" param: sortDirection (query, optional) "asc" | "desc" param: scheduled (query, optional) boolean returns: 200 { noteSummaries: object[]; workOrders: object[] } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-work-orders/ POST /api/work-orders [post-api-work-orders] Create a work order Staff must supply a unit. Tenant requests are forced to `source: tenant` and inherit the property, unit, and tenant from the caller active lease. auth: Bearer token required body: { assignedStaffUserId?: string; assignedVendorId?: string; category?: "plumbing" | "electrical" | "hvac" | "appliance" | "structural" | "pest_control" | "landscaping" | "general" | "other"; description?: string; entryInstructions?: string; priority?: "low" | "normal" | "high" | "emergency"; propertyId: string; scheduledAt?: string; source?: "staff" | "tenant"; subcategory?: string; tenantId?: string; title: string; unitId?: string } returns: 201 { workOrder: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/post-api-work-orders/ GET /api/work-orders/{id} [get-api-work-orders-by-id] Get a work order with notes, expenses, and attachments auth: Bearer token required param: id (path, required) string returns: 200 { attachmentCount: integer; attachments: object[]; linkedExpenses: object[]; notes: object[]; workOrder: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-work-orders-by-id/ PUT /api/work-orders/{id} [put-api-work-orders-by-id] Update a work order auth: Bearer token required param: id (path, required) string body: { category?: "plumbing" | "electrical" | "hvac" | "appliance" | "structural" | "pest_control" | "landscaping" | "general" | "other"; description?: string | null; entryInstructions?: string | null; priority?: "low" | "normal" | "high" | "emergency"; propertyId?: string; scheduledAt?: string | null; subcategory?: string | null; tenantId?: string | null; title?: string; unitId?: string | null } returns: 200 { workOrder: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/put-api-work-orders-by-id/ POST /api/work-orders/{id}/assign [post-api-work-orders-by-id-assign] Assign a work order to a vendor or staff user auth: Bearer token required param: id (path, required) string body: { assignedStaffUserId?: string | null; assignedVendorId?: string | null } returns: 200 { workOrder: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/post-api-work-orders-by-id-assign/ GET /api/work-orders/{id}/notes [get-api-work-orders-by-id-notes] List notes on a work order Tenant callers only see notes whose visibility includes tenants. auth: Bearer token required param: id (path, required) string returns: 200 { notes: object[] } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/get-api-work-orders-by-id-notes/ POST /api/work-orders/{id}/notes [post-api-work-orders-by-id-notes] Add a note to a work order auth: Bearer token required param: id (path, required) string body: { body: string; visibility: "organization_only" | "tenant_shared" | "vendor_shared" | "tenant_vendor_shared" } returns: 201 { note: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/post-api-work-orders-by-id-notes/ POST /api/work-orders/{id}/status [post-api-work-orders-by-id-status] Transition a work order status Allowed transitions: open to in_progress or cancelled; in_progress to completed or cancelled. Completed and cancelled are terminal. auth: Bearer token required param: id (path, required) string body: { status: "open" | "in_progress" | "completed" | "cancelled" } returns: 200 { workOrder: object } returns: 400 { code?: string; errors?: object[]; message: string } returns: 401 { code?: string; errors?: object[]; message: string } returns: 403 { code?: string; errors?: object[]; message: string } returns: 404 { code?: string; errors?: object[]; message: string } returns: 409 { code?: string; errors?: object[]; message: string } docs: https://docs.getvespy.com/api/operations/post-api-work-orders-by-id-status/