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.