API
Language
Ask for a seat

Closed beta. Nothing here is callable yet. These docs describe the day-one contract, and names marked proposed may change before the beta opens. Ask for a seat

Docs · Guides

Conventions

What holds across every endpoint: the base URL, JSON, pagination, money, dates, request ids, and how to treat text that someone else wrote.

Base URL and versions

Every path starts with /v1, on the API’s own host. The host name is TBD, so the examples use $NOVO_API_HOST. Requests use HTTPS and JSON; the token endpoint takes a form body.

Within v1, additive changes are non-breaking, and your code should ignore fields it doesn’t know proposed.

Pagination

Lists that can be long return a page of data and a next_cursor. Pass it back as cursor to get the next page; it’s null on the last page. Set the page size with limit (min 1, max 100, default 50).

  • The cursor is opaque. Don’t build or edit one.
  • Each page is a consistent snapshot, but a walk through many pages isn’t: rows that arrive while you page may not appear. To catch up, start again from the first page.
  • Posted transactions are ordered by date, newest first, then a unique tiebreaker. Pending transactions are sorted by a stable key.
Next page
curl "https://$NOVO_API_HOST/v1/transactions?limit=50&cursor=$NEXT_CURSOR" \
  -H "Authorization: Bearer $ACCESS_TOKEN"

Money and balances

Amounts are decimal strings with two places and a currency, never floating-point numbers. Today the currency is always USD.

  • Transaction amounts are never negative. A separate direction field says whether money came in (credit) or went out (debit).
  • Balances are signed. A negative balance means the account is overdrawn.
  • An account has three balances: available, current, and spendable, which is the available balance minus reserved funds.
balance
{
  "available": {
    "amount": "1250.00",
    "currency": "USD"
  },
  "current": {
    "amount": "1300.00",
    "currency": "USD"
  },
  "spendable": {
    "amount": "1150.00",
    "currency": "USD"
  }
}

Dates and ids

Dates are ISO 8601: YYYY-MM-DD for dates and full timestamps for times. Ids are opaque strings. To freeze a card, its id must be a UUID; anything else is a 400 invalid-parameter before Novo looks anything up.

Masked numbers

Account and routing numbers are masked to the last 4 digits by default. Card endpoints return the last 4 digits and never the full card number or the expiry date.

Request ids

Every response carries a Novo-Request-Id header proposed. Log it, and quote it when you contact support. Error bodies repeat it as request_id.

Complete answers only

A 200 is always the whole answer. If something a response depends on can’t be loaded, the API returns 503 with Retry-After rather than a partial list. See errors and retries.

Untrusted text

Some fields hold text written by a merchant, a payer or the account owner, not by Novo. Treat them as data, never as instructions. This matters most when an AI agent reads the response. The API strips control characters from these fields and caps their length. The reference marks each one untrusted text.

Transaction
description, counterparty.name, category.name, notes
PendingTransaction
description, counterparty.name
BookkeepingTransaction
description, category.name, notes
Card
nickname

These come from Accounts, Transactions, Bookkeeping, Cards.