API ReferenceLivev0.1.0-prototype

UnitBoard API

The UnitBoard API is the same surface every screen in the product speaks to — accounts payable, work orders, copilot, search, and reports. No integration tolls, no double-entry, no proprietary file dumps.

Base URL
https://unitboard.ai/api
Format
JSON · OpenAPI 3.1

Authentication

Authenticated endpoints accept a Bearer token in the Authorization header. Tokens are scoped to your organization and can be rotated at any time. Internal traffic uses Supabase session cookies; both forms are accepted.

Health

Liveness and service status.

get/api/health

Liveness probe

Returns 200 with a small JSON envelope when the service is up. No auth required.

Response 200

Service is healthy.

okrequired
boolean
servicerequired
string
timestamprequired
string (date-time)

Accounts Payable

Invoice intake, AI extraction, approval, and rejection. Approving posts a journal entry to the GL.

post/api/ap/extract

Extract invoice from PDF

Runs Claude Vision over a base64-encoded PDF, matches the vendor against the directory, suggests a GL coding, and persists a draft invoice (status `extracted`) ready for human review.

Authentication required. Send a Bearer token in the Authorization header.

Request body

filenamerequired
string
pdfBase64required
string

Base64-encoded PDF body. The data-URL prefix (`data:application/pdf;base64,`) is tolerated and stripped server-side.

Response 200

Invoice extracted and persisted as a draft.

okrequired
boolean
invoiceIdrequired
string (uuid)
durationMsrequired
integer
vendorrequired
string

Matched vendor name, or the raw extracted name.

accountrequired
string | null

GL account suggestion in `code — name` form, or null when no match.

confidencerequired
number

post/api/ap/approve

Approve and post invoice

Posts a journal entry (debit each line's GL account, credit AP control) and marks the invoice `posted`. Idempotent on already-posted invoices is NOT guaranteed — caller should check `status` first.

Authentication required. Send a Bearer token in the Authorization header.

Request body

invoiceIdrequired
string (uuid)

Response 200

Invoice approved and posted to the GL.

okrequired
boolean
journalEntryIdrequired
string (uuid)

post/api/ap/reject

Reject invoice

Marks an invoice as `rejected`. Does not post to the GL.

Authentication required. Send a Bearer token in the Authorization header.

Request body

invoiceIdrequired
string (uuid)

Response 200

Invoice marked rejected.

okrequired
boolean

Work Orders

Maintenance work order lifecycle — creation and status changes.

post/api/work-orders/create

Create work order

Opens a new maintenance work order on the given property (and optionally a unit / vendor). Defaults `priority=normal`, `status=open`.

Authentication required. Send a Bearer token in the Authorization header.

Request body

titlerequired
string
description
string | null
propertyIdrequired
string (uuid)
unitId
string | null
priority
enum
lownormalhighurgent
estimatedCost
number | null
vendorId
string | null

Response 200

Work order created.

okrequired
boolean
idrequired
string (uuid)

post/api/work-orders/update-status

Update work order status

Transitions a work order to one of the canonical statuses. When set to `completed`, `closed_at` is stamped to now; any other status clears `closed_at` so re-opens stay honest.

Authentication required. Send a Bearer token in the Authorization header.

Request body

idrequired
string (uuid)
statusrequired
enum
openin_progresson_holdcompletedcanceled

Response 200

Status updated.

okrequired
boolean

Copilot

Natural-language ledger and operations queries. Agentic tool-use loop over Anthropic Claude.

post/api/copilot/query

Natural-language query

Runs an agentic tool-use loop over Claude. The model has read access to ledger / property / leasing tools and is capped at 5 tool-call rounds. Pass the full conversation history each call — the route is stateless.

Authentication required. Send a Bearer token in the Authorization header.

Request body

messagesrequired
array<object>

Response 200

Final answer produced.

answerrequired
string
toolCallsrequired
array<string>

Tool names invoked, in order. Empty when the model answered from context alone.

Search

Global cross-entity search — properties, units, residents, leases, vendors, invoices, work orders, journal entries.

Reports

Packaged financial and operational statements. JSON by default; pass ?format=csv for an attachment.

get/api/reports/{slug}

Run a packaged report

Runs the named report and returns either a JSON shape (default) suitable for rendering, or a `text/csv` download when `?format=csv`. The same registry powers the in-app report tables, so JSON / CSV / table are always in agreement.

Authentication required. Send a Bearer token in the Authorization header.

Path parameters

NameTypeRequiredDescription
slugenumrequiredReport identifier.
profit-and-lossbalance-sheetcash-flowrent-rolldelinquencylease-expirations

Query parameters

NameTypeRequiredDescription
formatenumoptionalPass `csv` to download a CSV attachment instead of JSON.
csv
periodenumoptionalTime window in days. Only honored by reports that support a period.
3090180365ytd

Response 200

Report payload.

okrequired
boolean
slugrequired
string
titlerequired
string
columnsrequired
array<object>
rowsrequired
array<object>
totals
object | null
summary
array | null
periodLabel
string | null
periodDays
integer | null

Activity

Cross-entity activity feed (audit log).

get/api/activity

Cross-entity activity feed

Reverse-chronological activity events across properties, leases, invoices, journal entries, and work orders. Useful as an audit log or dashboard widget.

Authentication required. Send a Bearer token in the Authorization header.

Query parameters

NameTypeRequiredDescription
limitintegeroptionalMax number of events to return.
sincestring (date-time)optionalReturn events at or after this ISO-8601 timestamp.

Response 200

Activity events.

eventsrequired
array<object>

Admin

Privileged endpoints requiring the admin role.

post/api/admin/set-role

Set user role

Updates a user's role. Only callers with the `admin` role may invoke this; uses the Supabase service role internally to bypass RLS.

Authentication required. Send a Bearer token in the Authorization header.

Request body

userIdrequired
string (uuid)
rolerequired
enum
adminoperatoraccountantviewer

Response 200

Role updated.

okrequired
boolean

Auth

Supabase authentication callbacks.

get/auth/callback

Supabase auth callback

Magic-link / OAuth callback. Exchanges the `code` query param for a session cookie, then redirects to `next` (default `/dashboard`). On failure, redirects to `/login?error=auth_callback_failed`.

Query parameters

NameTypeRequiredDescription
codestringrequiredAuthorization code issued by Supabase.
nextstringoptionalPath to redirect to on success.

Payments

post/api/payments/create

Create payment

Records a rent or fee payment against a lease. Use this from a spoke (e.g. PayUp) to push collection events into the hub. `status` defaults to `pending` — switch to `succeeded` once the underlying processor settles.

Authentication required. Send a Bearer token in the Authorization header.

Request body

leaseIdrequired
string (uuid)
residentId
string | null
amountrequired
number
currency
enum
USDCAD
methodrequired
enum
cardachcashcheckwire
status
enum
pendingprocessingsucceededfailedrefundedcancelled
description
string | null
stripePaymentIntentId
string | null
stripeChargeId
string | null
feeAmount
number | null
paidAt
string | null

Response 200

Payment recorded.

okrequired
boolean

AP

post/api/invoices/create

Create invoice

Posts a vendor invoice into the AP queue. Spokes like BillRoute push extracted invoice rows here. If `lines` is provided, GL lines are written with `accountCode` resolved against the chart of accounts.

Authentication required. Send a Bearer token in the Authorization header.

Request body

vendorIdrequired
string (uuid)
propertyId
string | null
invoiceNumberrequired
string
invoiceDaterequired
string (date)
dueDaterequired
string (date)
subtotalrequired
number
tax
number
totalrequired
number
status
enum
extractedpending_approvalapprovedpaidposted
description
string | null
lines
array<object>

Response 200

Invoice created.

okrequired
boolean

Vendors

post/api/vendors/create

Create vendor

Adds a vendor to the directory. Spokes like IDCore push verified vendors here with EIN, contact, and a default GL coding hint.

Authentication required. Send a Bearer token in the Authorization header.

Request body

namerequired
string
email
string | null
phone
string | null
ein
string | null
addressLine1
string | null
addressLine2
string | null
city
string | null
state
string | null
zip
string | null
defaultAccountCode
string | null

Chart-of-accounts code; resolved to the default_account_id on insert.

Response 200

Vendor created.

okrequired
boolean

Notices

post/api/notices/create

Create legal notice

Drafts a state-jurisdiction-aware legal notice (pay-or-quit, lease violation, holdover, etc.) against a lease. Use the Notices service-flow endpoints to advance lifecycle (serve / cure / escalate).

Authentication required. Send a Bearer token in the Authorization header.

Request body

leaseIdrequired
string (uuid)
typerequired
string

notice_type enum value

jurisdictionStaterequired
string
templateVersion
string | null
daysToCure
number | null
balanceDue
number | null
postedDate
string | null
status
string

Response 200

Notice drafted.

okrequired
boolean

Properties

post/api/properties/create

Create property

Adds a managed property to the org. Either bearer-token authed (typical spoke usage) or cookie-session authed (UI form).

Authentication required. Send a Bearer token in the Authorization header.

Request body

namerequired
string
address_line_1required
string
address_line_2
string | null
cityrequired
string
staterequired
string
ziprequired
string
total_units
integer | null
year_built
integer | null

Response 200

Property created.

okrequired
boolean