Org-wide scheduled occurrences for ONE calendar month
const url = 'https://api.tovarifinancial.com/bills/due?month=2026-07';const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}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.
Authorizations
Section titled “Authorizations”Parameters
Section titled “Parameters”Query Parameters
Section titled “Query Parameters”Month, ‘YYYY-MM’
Example
2026-07The 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.
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.
Responses
Section titled “Responses”The month’s scheduled occurrences
object
object
The month that was requested, echoed back as ‘YYYY-MM’.
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.
object
The occurrence’s ORIGINAL scheduled date. This — never effectiveDueDate — is what decides month membership, status and daysUntil.
Day-of-month of dueDate, for the panel’s grouping.
SIGNED (income +, expense −) — the schedule’s own amount.
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.
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.
object
Calendar date, ‘YYYY-MM-DD’
Integer minor units (cents)
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.
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.
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.
“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.
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.
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.
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.
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.
Example
{ "data": { "month": "2026-07", "occurrences": [ { "direction": "expense", "status": "paid", "occurrenceStatus": "upcoming", "registerReflection": "pending_match" } ] }}Validation failed — see errorCode / fieldErrors
object
Machine-readable error code (AUTH_ERROR_CODES).
Optional field-level validation errors, keyed by field name.
object
Example
{ "errorCode": "INVALID_EMAIL_FORMAT"}Missing, invalid, or expired bearer token
object
Machine-readable error code (AUTH_ERROR_CODES).
Optional field-level validation errors, keyed by field name.
object
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.
object
Which precondition refused the request. Evaluated in this order (CCR-1); SUBSCRIPTION_REQUIRED is unreachable while BILLING_ENABLED is not exactly true.
object
Active policy versions the user has not yet accepted.
object
True when the user has accepted no policy before — the client renders the new-signup screen rather than the re-acceptance one.
Example
{ "errorCode": "EMAIL_NOT_VERIFIED"}Internal error (no internal detail leaked)
object
Machine-readable error code (AUTH_ERROR_CODES).
Optional field-level validation errors, keyed by field name.
object
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.
object
Machine-readable error code (AUTH_ERROR_CODES).
Optional field-level validation errors, keyed by field name.
object
Example
{ "errorCode": "INVALID_EMAIL_FORMAT"}