Skip to content

Safe-to-spend disposable-cash figure

GET
/dashboard/safe-to-spend
curl --request GET \
--url https://api.tovarifinancial.com/dashboard/safe-to-spend \
--header 'Authorization: Bearer <token>'

Safe-to-spend DTO. Order of accountBreakdown[] mirrors includedAccounts[] and is rendered positionally; SUM(clearToSpendCents) === safeToSpendCents by construction.

Media typeapplication/json
object
data
required
object
state
required

Server-authoritative tri-state, one rule for both branches: safeToSpendCents < 0 => negative; <= tightThresholdCents => tight; otherwise healthy. The threshold is always >= 0, so $0.00 is structurally never “healthy”. Clients must not re-derive this from a client-side threshold.

string
Allowed values: healthy tight negative
stateBasis
required

Why the state reads the way it does. INFORMATIONAL except for ‘no-accounts’, which clients MUST consult BEFORE state to show the connect-an-account affordance (the empty branch’s $0 headline is a structural zero, not a measurement). ‘typical-spending’ when tightThresholdCents > 0; ‘zero-threshold’ when it is 0 (no history and no plan — no cushion is fabricated).

string
Allowed values: no-accounts typical-spending zero-threshold
tightThresholdCents
required

One pay period of typical spending: (customarySpendCents + budgeted non-bill-linked targets) x cycleDays / 30.4375, decimal.js ROUND_HALF_UP, clamped at 0.

integer format: int64
cycleDays
required

Whole days from today through horizonDate, INCLUSIVE of both ends (a horizon of today is 1).

integer
accountBreakdown
required
Array<object>
object
accountId
required
string format: uuid
name
required
string
accountType
required

Only checking/savings can appear — migration 014’s CHECK forces include_in_safe_to_spend = FALSE for investment/credit_card/loan.

string
Allowed values: checking savings
maskLast4
required
string
nullable
balanceCents
required

Integer minor units (cents). Equals the matching includedAccounts[] entry.

integer format: int64
billsDueCents
required

Signed sum of this account’s obligations (negative for net outflow).

integer format: int64
clearToSpendCents
required

BalanceCents + billsDueCents. SIGNED and never floored.

integer format: int64
willOverdraw
required

ClearToSpendCents < 0.

boolean
obligationBillIds
required

The bills behind billsDueCents, de-duplicated, in first-occurrence order by dateIso.

Array<string>
key
additional properties
any
message
string
requestId
required
string
timestamp
required
string format: date-time
Example
{
"data": {
"state": "healthy",
"stateBasis": "no-accounts",
"accountBreakdown": [
{
"accountType": "checking"
}
]
}
}

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 ORG_NAME_TAKEN 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 ORG_NAME_TAKEN 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 ORG_NAME_TAKEN 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"
}