Skip to content

Org-wide scheduled occurrences for ONE calendar month

GET
/bills/due
curl --request GET \
--url 'https://api.tovarifinancial.com/bills/due?month=2026-07' \
--header 'Authorization: Bearer <token>'

The month-at-a-time companion to GET /bills/scheduled, and a different question: that one is per-ACCOUNT, cursor-floored and forward-looking (“what does this register still owe”), while this one is ORG-WIDE over a single calendar month (“what is scheduled this month”) and therefore still lists occurrences the household has already paid, marked paid, so a caller can render them muted rather than hiding them. There is no account parameter on any path: the account universe is org-wide and categoryId narrows a different axis entirely. SIGN CONVENTION: amountCents and totalCents are SIGNED (income +, expense −) — the month lists both directions, unlike the Planning grid’s positive-magnitude billsCents. Since KAN-2926 every occurrence also carries the whole exception row — note, skipped, forecastDate and forecastAmountCents — spelled exactly as GET /bills/scheduled spells them, so one client reader serves both surfaces.

month
required

Month, ‘YYYY-MM’

string
Example
2026-07

The calendar month ‘YYYY-MM’ (REQUIRED). Membership is decided by each occurrence’s ORIGINAL due date, so neither a declared payment date nor a forecast date can pull an occurrence into or out of the month it belongs to. A missing or malformed value is a 400 on month — it is never defaulted to the current month.

categoryId
string format: uuid

Optional: narrows to the bills filed under exactly this budget category. Absent means no category narrowing. A malformed id is a 400 on categoryId; an id belonging to another org simply matches nothing under RLS and answers a normal 200 with no occurrences, never a 404. It narrows the CATEGORY axis only — the ACCOUNT universe stays org-wide on every path. It narrows only which occurrences are LISTED (KAN-1033): the bank-match pool behind occurrenceStatus / registerReflection is never narrowed by it.

The month’s scheduled occurrences

Media typeapplication/json
object
data
required
object
month

The month that was requested, echoed back as ‘YYYY-MM’.

string
totalCents

The SCHEDULE’s signed sum for the month (income +, expense −), over every occurrence returned. It is deliberately UNMOVED by a declaration, a forecast override or a skip (KAN-2926): on this surface the header figure and the rows beneath it are both read from the schedule, so the header cannot disagree with itself. This is the one place it differs from /bills/scheduled’s totalDueCents, which DOES follow the rows.

integer format: int64
occurrences
Array<object>
object
billId
string
name
string
payeeId
string
nullable
dueDate

The occurrence’s ORIGINAL scheduled date. This — never effectiveDueDate — is what decides month membership, status and daysUntil.

string
dayOfMonth

Day-of-month of dueDate, for the panel’s grouping.

integer
amountCents

SIGNED (income +, expense −) — the schedule’s own amount.

integer format: int64
direction
string
Allowed values: expense income
budgetCategoryId
string
nullable
categoryName
string
nullable
categoryColorId
string
nullable
status

UNCHANGED by KAN-2447 and KAN-2926, and NOT the /bills/scheduled occurrenceStatus union: ‘scheduled’ here means “outstanding, not yet due” and says nothing about a marked-scheduled declaration. Derived from dueDate and the settlement history, so no override can move it.

string
Allowed values: paid overdue scheduled
daysUntil

Whole days from the client’s local today to dueDate; NEGATIVE when the occurrence is in the past. Measured from the ORIGINAL due date, like status.

integer
scheduledMark
object
scheduledPaymentDate
required

Calendar date, ‘YYYY-MM-DD’

string
amountCents
required

Integer minor units (cents)

integer format: int64
effectiveDueDate

The occurrence’s effective date, resolved server-side as declaration → forecast → schedule (KAN-2926): scheduledMark ? its scheduledPaymentDate : forecastDate ?? this row’s own dueDate. dueDate keeps its own meaning and value.

string
effectiveAmountCents

SIGNED (income +, expense −), server-computed as declaration → forecast → schedule (KAN-2926). Equals the schedule’s own signed amount when no override is present. Never re-derive a sign on the client.

integer format: int64
note
required

The household’s own free text on THIS occurrence, or null (KAN-2913). ALWAYS emitted. A SIBLING of scheduledMark, never a member of it: a note asserts nothing about a payment. Spelled identically on GET /bills/scheduled and GET /bills/due; /bills/projection omits it, having no consumer that renders free text.

string
nullable
skipped
required

“Do not count this one” (KAN-2913). ALWAYS emitted. The row STAYS in the list and keeps its own amountCents and effectiveAmountCents; what changes is only how a client renders it: this surface has no projected balance and no rows-derived footer, and totalCents, status, daysUntil and month membership are all read from the schedule, so a skip moves no figure on it. It is not POST /bills/{id}/skip — no cursor moves and no payment history is written.

boolean
forecastDate
required

The FORECAST-ONLY date override on this occurrence, or null (KAN-2926). ALWAYS emitted. Outranked by scheduledMark when both are present. It moves presentation and the projected step only — never month bucketing, window membership or Safe to Spend.

string
nullable
forecastAmountCents
required

The FORECAST-ONLY amount override, as the POSITIVE MAGNITUDE it is stored as, or null (KAN-2926). ALWAYS emitted. The signed figure is effectiveAmountCents; never re-sign this on the client. Outranked by scheduledMark when both are present.

integer format: int64
nullable
occurrenceStatus
required

KAN-1033 — the server’s ONE render discriminator (the union GET /bills and GET /bills/scheduled emit), resolved through the same precedence: payment_pending when a PENDING bank row covers this occurrence at the unattended trust class, else marked_scheduled / overdue / upcoming from the declaration, the date and the skip. match_ambiguous is never emitted on this list (it renders no chooser). upcoming for an occurrence the cursor already passed. ALWAYS emitted by this server; older servers omit the key. Presentation only.

string
Allowed values: upcoming overdue payment_pending match_ambiguous marked_scheduled
registerReflection
required

KAN-1033 — WHY the matching engine says this occurrence is already in the register (the same answer GET /bills/scheduled gives), or null. Read from the shared covered-occurrence loader over the ACCOUNT-COMPLETE pool (never narrowed by a filter), only for an outstanding occurrence due on or before today + 7 days; null past that reach, for an occurrence already paid, and whenever the scan was skipped or failed (a failed scan never fails the response). It moves no figure: status, daysUntil, totalCents and month membership are unchanged, and a categoryId filter narrows only which occurrences are listed, never the pool, so a filtered request resolves each listed occurrence exactly as the unfiltered one does. ALWAYS emitted by this server (explicit null when none); older servers omit the key, and a client must tolerate an unknown future member.

string
nullable
Allowed values: pending_match payment_found tied_cover manual_entry
message
string
requestId
required
string
timestamp
required
string format: date-time
Example
{
"data": {
"month": "2026-07",
"occurrences": [
{
"direction": "expense",
"status": "paid",
"occurrenceStatus": "upcoming",
"registerReflection": "pending_match"
}
]
}
}

Validation failed — see errorCode / fieldErrors

Media typeapplication/json
object
errorCode
required

Machine-readable error code (AUTH_ERROR_CODES).

string
Allowed values: INVALID_EMAIL_FORMAT USER_ALREADY_EXISTS INVALID_INVITE_CODE WRONG_PASSWORD USER_NOT_FOUND AUTHENTICATION_FAILED EXPIRED_CODE INVALID_CODE INVALID_PASSWORD VALIDATION_ERROR SIGNUP_FAILED DATABASE_ERROR SERVICE_UNAVAILABLE PLAID_ERROR IDEMPOTENCY_CONFLICT ACCOUNT_ALREADY_LINKED NOT_FOUND
message
required
string
fieldErrors

Optional field-level validation errors, keyed by field name.

object
key
additional properties
Array<string>
requestId
required
string
timestamp
required
string format: date-time
Example
{
"errorCode": "INVALID_EMAIL_FORMAT"
}

Missing, invalid, or expired bearer token

Media typeapplication/json
object
errorCode
required

Machine-readable error code (AUTH_ERROR_CODES).

string
Allowed values: INVALID_EMAIL_FORMAT USER_ALREADY_EXISTS INVALID_INVITE_CODE WRONG_PASSWORD USER_NOT_FOUND AUTHENTICATION_FAILED EXPIRED_CODE INVALID_CODE INVALID_PASSWORD VALIDATION_ERROR SIGNUP_FAILED DATABASE_ERROR SERVICE_UNAVAILABLE PLAID_ERROR IDEMPOTENCY_CONFLICT ACCOUNT_ALREADY_LINKED NOT_FOUND
message
required
string
fieldErrors

Optional field-level validation errors, keyed by field name.

object
key
additional properties
Array<string>
requestId
required
string
timestamp
required
string format: date-time
Example
{
"errorCode": "INVALID_EMAIL_FORMAT"
}

Authenticated, but the tenant gate refuses the request until the caller resolves a precondition. errorCode is one of EMAIL_NOT_VERIFIED, POLICY_ACCEPTANCE_REQUIRED, or SUBSCRIPTION_REQUIRED, evaluated in exactly that order (contract term CCR-1: email verification first, then policy acceptance, then subscription — so a subscriber who has merely not re-accepted the current policies always sees POLICY_ACCEPTANCE_REQUIRED). A POLICY_ACCEPTANCE_REQUIRED body additionally carries details.outstanding (the policy versions still to accept) and details.firstAcceptance. The SUBSCRIPTION_REQUIRED arm is INERT unless the server-side BILLING_ENABLED flag is exactly the string true; while it is off, only the first two codes are reachable. Not retryable as sent — resolve the named condition, then resend.

Media typeapplication/json
object
errorCode
required

Which precondition refused the request. Evaluated in this order (CCR-1); SUBSCRIPTION_REQUIRED is unreachable while BILLING_ENABLED is not exactly true.

string
Allowed values: EMAIL_NOT_VERIFIED POLICY_ACCEPTANCE_REQUIRED SUBSCRIPTION_REQUIRED
message
required
string
details
object
outstanding
required

Active policy versions the user has not yet accepted.

Array<object>
object
id
required
string format: uuid
policyType
required
string
version
required
integer
title
required
string
firstAcceptance
required

True when the user has accepted no policy before — the client renders the new-signup screen rather than the re-acceptance one.

boolean
requestId
required
string
timestamp
required
string format: date-time
Example
{
"errorCode": "EMAIL_NOT_VERIFIED"
}

Internal error (no internal detail leaked)

Media typeapplication/json
object
errorCode
required

Machine-readable error code (AUTH_ERROR_CODES).

string
Allowed values: INVALID_EMAIL_FORMAT USER_ALREADY_EXISTS INVALID_INVITE_CODE WRONG_PASSWORD USER_NOT_FOUND AUTHENTICATION_FAILED EXPIRED_CODE INVALID_CODE INVALID_PASSWORD VALIDATION_ERROR SIGNUP_FAILED DATABASE_ERROR SERVICE_UNAVAILABLE PLAID_ERROR IDEMPOTENCY_CONFLICT ACCOUNT_ALREADY_LINKED NOT_FOUND
message
required
string
fieldErrors

Optional field-level validation errors, keyed by field name.

object
key
additional properties
Array<string>
requestId
required
string
timestamp
required
string format: date-time
Example
{
"errorCode": "INVALID_EMAIL_FORMAT"
}

Service temporarily unavailable — errorCode is SERVICE_UNAVAILABLE. A TRANSIENT, RETRYABLE condition rather than a defect in the request: a query that exceeded its time budget, a lost or refused database connection, a saturated connection pool, or an outage at an upstream provider the request depends on (the authentication provider, or the bank data provider on a bank-connection operation). The identical request may succeed on retry — back off briefly and, on a write, resend the same X-Idempotency-Key where the operation accepts one.

Media typeapplication/json
object
errorCode
required

Machine-readable error code (AUTH_ERROR_CODES).

string
Allowed values: INVALID_EMAIL_FORMAT USER_ALREADY_EXISTS INVALID_INVITE_CODE WRONG_PASSWORD USER_NOT_FOUND AUTHENTICATION_FAILED EXPIRED_CODE INVALID_CODE INVALID_PASSWORD VALIDATION_ERROR SIGNUP_FAILED DATABASE_ERROR SERVICE_UNAVAILABLE PLAID_ERROR IDEMPOTENCY_CONFLICT ACCOUNT_ALREADY_LINKED NOT_FOUND
message
required
string
fieldErrors

Optional field-level validation errors, keyed by field name.

object
key
additional properties
Array<string>
requestId
required
string
timestamp
required
string format: date-time
Example
{
"errorCode": "INVALID_EMAIL_FORMAT"
}