excited.liveexcited.live
API reference

Accounting

Per-resource accounting API: entities, assets, incomes, expenses, liabilities and transfers, plus computed summary (wealth and balance sheet), ledger, cash-flows, liability schedules and projection.

List entities

GET /api/v1/accounting/entities

Bootstraps the personal entity and its default wallet on first call.

Responses

  • 200 — Entities. Entity[]
  • 401 — Missing or invalid credential (session token or API key; only when auth is configured). Error
curl "$API_URL/api/v1/accounting/entities" \
  -H "Authorization: Bearer $TOKEN"

Create a business entity

POST /api/v1/accounting/entities

Business only. Also creates its default cash asset, “<name> Main Wallet”, at ฿0.

Request body (application/json)

Type: object

FieldTypeRequiredDescription
idstringnoOptional client-generated UUID used as the record id. Repeating a create with the same id must not add a second record: the MCP create tools return the stored record with deduplicated: true, and the REST routes answer 409 DUPLICATE.
type"personal" | "business"noOnly business can be created; the personal entity is created on first use.
asOfstringnoClient’s current month or day. For cycle: "one_time", a day-precision value such as 2026-10-26 is the date of the receipt (it sets dayOfMonth); a month-only value lands on the 1st. Otherwise the default month for startMonth.
namestringyes
currencystringno
targetSafetyBuffernumberno
activebooleanno
notesstringno
imageUrlstringno

Responses

  • 201 — Entity created. Entity
  • 400 — Validation error. Error
  • 401 — Missing or invalid credential (session token or API key; only when auth is configured). Error
  • 404 — Record not found. Error
  • 409 — Version conflict or duplicate id. Error
curl -X POST "$API_URL/api/v1/accounting/entities" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ ... }'

Get an entity

GET /api/v1/accounting/entities/{id}

Parameters

NameInTypeRequiredDescription
idpathstringyes

Responses

  • 200 — The entity. Entity
  • 401 — Missing or invalid credential (session token or API key; only when auth is configured). Error
  • 404 — Record not found. Error
curl "$API_URL/api/v1/accounting/entities/:id" \
  -H "Authorization: Bearer $TOKEN"

Update an entity

PATCH /api/v1/accounting/entities/{id}

Partial update. The entity type cannot change.

Parameters

NameInTypeRequiredDescription
idpathstringyes

Request body (application/json)

Type: object

FieldTypeRequiredDescription
versionintegernoStored version the caller last read; a mismatch returns 409.
type"personal" | "business"noMust match the stored type; entity type cannot change.
namestringno
currencystring | nullno
targetSafetyBuffernumber | nullno
activeboolean | nullno
notesstring | nullno
imageUrlstring | nullno

Responses

  • 200 — Entity updated. Entity
  • 400 — Validation error. Error
  • 401 — Missing or invalid credential (session token or API key; only when auth is configured). Error
  • 404 — Record not found. Error
  • 409 — Version conflict or duplicate id. Error
curl -X PATCH "$API_URL/api/v1/accounting/entities/:id" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ ... }'

Delete a business entity

DELETE /api/v1/accounting/entities/{id}

The personal entity cannot be deleted. Deleting cascades to all of its records.

Parameters

NameInTypeRequiredDescription
idpathstringyes

Responses

  • 200 — Entity deleted. Ok
  • 400 — Validation error. Error
  • 401 — Missing or invalid credential (session token or API key; only when auth is configured). Error
  • 404 — Record not found. Error
  • 409 — Version conflict or duplicate id. Error
curl -X DELETE "$API_URL/api/v1/accounting/entities/:id" \
  -H "Authorization: Bearer $TOKEN"

List assets

GET /api/v1/accounting/assets

Parameters

NameInTypeRequiredDescription
entityIdquerystringno
kindquery"cash" | "fixed" | "investment"no

Responses

  • 200 — Assets. Asset[]
  • 400 — Validation Error object
  • 401 — Missing or invalid credential (session token or API key; only when auth is configured). Error
curl "$API_URL/api/v1/accounting/assets" \
  -H "Authorization: Bearer $TOKEN"

Create an asset

POST /api/v1/accounting/assets

Body discriminated by kind. Fixed and investment assets accept paidFrom (creates the purchase transfer in the same write); fixed assets accept financing (creates a loan liability, paid at its level payment unless amount is given). A cash asset with isDefault clears the entity’s other defaults; an entity’s first cash asset is always the default.

Request body (application/json)

Type: object | object | object

Responses

  • 201 — Asset created. Asset
  • 400 — Validation error. Error
  • 401 — Missing or invalid credential (session token or API key; only when auth is configured). Error
  • 404 — Record not found. Error
  • 409 — Version conflict or duplicate id. Error
curl -X POST "$API_URL/api/v1/accounting/assets" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ ... }'

Get an asset

GET /api/v1/accounting/assets/{id}

Parameters

NameInTypeRequiredDescription
idpathstringyes

Responses

  • 200 — The asset. Asset
  • 401 — Missing or invalid credential (session token or API key; only when auth is configured). Error
  • 404 — Record not found. Error
curl "$API_URL/api/v1/accounting/assets/:id" \
  -H "Authorization: Bearer $TOKEN"

Update an asset

PATCH /api/v1/accounting/assets/{id}

Partial update. kind and entityId cannot change.

Parameters

NameInTypeRequiredDescription
idpathstringyes

Request body (application/json)

Type: object

FieldTypeRequiredDescription
versionintegernoStored version the caller last read; a mismatch returns 409.
namestringno
categorystringno
activeboolean | nullno
notesstring | nullno
imageUrlstring | nullno
detailsmap of any | nullno
balancenumber | nullno
balanceAsOfstring | nullno
currencystring | nullno
isDefaultboolean | nullno
costnumberno
acquiredOnstringno
depreciationMethod"straight_line" | "none" | nullno
usefulLifeMonthsinteger | nullno
salvageValuenumber | nullno
instrumentstringno
symbolstring | nullno
unitsnumber | nullno
costBasisnumber | nullno
marketValuenumber | nullno
valuedAsOfstring | nullno
expectedAnnualReturnnumber | nullno

Responses

  • 200 — Asset updated. Asset
  • 400 — Validation error. Error
  • 401 — Missing or invalid credential (session token or API key; only when auth is configured). Error
  • 404 — Record not found. Error
  • 409 — Version conflict or duplicate id. Error
curl -X PATCH "$API_URL/api/v1/accounting/assets/:id" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ ... }'

Delete an asset

DELETE /api/v1/accounting/assets/{id}

Deleting the default cash asset promotes the oldest remaining cash asset of the entity.

Parameters

NameInTypeRequiredDescription
idpathstringyes

Responses

  • 200 — Asset deleted. Ok
  • 400 — Validation error. Error
  • 401 — Missing or invalid credential (session token or API key; only when auth is configured). Error
  • 404 — Record not found. Error
  • 409 — Version conflict or duplicate id. Error
curl -X DELETE "$API_URL/api/v1/accounting/assets/:id" \
  -H "Authorization: Bearer $TOKEN"

List incomes

GET /api/v1/accounting/incomes

Parameters

NameInTypeRequiredDescription
entityIdquerystringno
kindquery"employment" | "business" | "investment" | "other"no

Responses

  • 200 — Incomes. Income[]
  • 400 — Validation Error object
  • 401 — Missing or invalid credential (session token or API key; only when auth is configured). Error
curl "$API_URL/api/v1/accounting/incomes" \
  -H "Authorization: Bearer $TOKEN"

Create an income

POST /api/v1/accounting/incomes

employment only for kind employment; sourceAssetId only for kind investment.

Request body (application/json)

Type: object | object | object | object

Responses

  • 201 — Income created. Income
  • 400 — Validation error. Error
  • 401 — Missing or invalid credential (session token or API key; only when auth is configured). Error
  • 404 — Record not found. Error
  • 409 — Version conflict or duplicate id. Error
curl -X POST "$API_URL/api/v1/accounting/incomes" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ ... }'

Get an income

GET /api/v1/accounting/incomes/{id}

Parameters

NameInTypeRequiredDescription
idpathstringyes

Responses

  • 200 — The income. Income
  • 401 — Missing or invalid credential (session token or API key; only when auth is configured). Error
  • 404 — Record not found. Error
curl "$API_URL/api/v1/accounting/incomes/:id" \
  -H "Authorization: Bearer $TOKEN"

Update an income

PATCH /api/v1/accounting/incomes/{id}

Parameters

NameInTypeRequiredDescription
idpathstringyes

Request body (application/json)

Type: object

FieldTypeRequiredDescription
versionintegernoStored version the caller last read; a mismatch returns 409.
namestringno
categorystringno
amountnumberno
cycle"weekly" | "monthly" | "quarterly" | "semi-annual" | "yearly" | "one_time" | nullno
dayOfMonthinteger | nullno
startMonthstring | nullno
endMonthstring | nullno
taxCategory"40_1" | "40_2" | "40_3" | "40_4" | "40_5" | "40_6" | "40_7" | "40_8" | nullno
depositAssetIdstring | nullno
activeboolean | nullno
notesstring | nullno
imageUrlstring | nullno
detailsmap of any | nullno
employmentobjectno
employment.employerstringno
employment.titlestringno
sourceAssetIdstringno

Responses

  • 200 — Income updated. Income
  • 400 — Validation error. Error
  • 401 — Missing or invalid credential (session token or API key; only when auth is configured). Error
  • 404 — Record not found. Error
  • 409 — Version conflict or duplicate id. Error
curl -X PATCH "$API_URL/api/v1/accounting/incomes/:id" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ ... }'

Delete an income

DELETE /api/v1/accounting/incomes/{id}

Parameters

NameInTypeRequiredDescription
idpathstringyes

Responses

  • 200 — Income deleted. Ok
  • 400 — Validation error. Error
  • 401 — Missing or invalid credential (session token or API key; only when auth is configured). Error
  • 404 — Record not found. Error
  • 409 — Version conflict or duplicate id. Error
curl -X DELETE "$API_URL/api/v1/accounting/incomes/:id" \
  -H "Authorization: Bearer $TOKEN"

Set the career salary

POST /api/v1/accounting/incomes/career

Updates the entity’s primary employment income (earliest startMonth), or creates one when salary > 0. A salary of 0 deactivates the primary income.

Request body (application/json)

Type: object

FieldTypeRequiredDescription
entityIdstringyes
salarynumberyes
paydayDayOfMonthintegerno
titlestringno
companystringno
imageUrlstringno
startMonthstring | ""noYYYY-MM. Empty string keeps the existing start month.
endMonthstring | ""noYYYY-MM. Empty string clears the end month.
asOfstringnoClient’s current month or day. For cycle: "one_time", a day-precision value such as 2026-10-26 is the date of the receipt (it sets dayOfMonth); a month-only value lands on the 1st. Otherwise the default month for startMonth.

Responses

  • 200 — Primary income, or null when none exists. object
  • 400 — Validation error. Error
  • 401 — Missing or invalid credential (session token or API key; only when auth is configured). Error
  • 404 — Record not found. Error
  • 409 — Version conflict or duplicate id. Error
curl -X POST "$API_URL/api/v1/accounting/incomes/career" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ ... }'

List expenses

GET /api/v1/accounting/expenses

Parameters

NameInTypeRequiredDescription
entityIdquerystringno

Responses

  • 200 — Expenses. Expense[]
  • 400 — Validation Error object
  • 401 — Missing or invalid credential (session token or API key; only when auth is configured). Error
curl "$API_URL/api/v1/accounting/expenses" \
  -H "Authorization: Bearer $TOKEN"

Create an expense

POST /api/v1/accounting/expenses

Request body (application/json)

Type: object

FieldTypeRequiredDescription
idstringnoOptional client-generated UUID used as the record id. Repeating a create with the same id must not add a second record: the MCP create tools return the stored record with deduplicated: true, and the REST routes answer 409 DUPLICATE.
entityIdstringyes
asOfstringnoClient’s current month or day. For cycle: "one_time", a day-precision value such as 2026-10-26 is the date of the receipt (it sets dayOfMonth); a month-only value lands on the 1st. Otherwise the default month for startMonth.
namestringyes
category"ai" | "capital_deploy" | "connectivity" | "dev_tool" | "entertainment" | "family" | "food" | "groceries" | "healthcare" | "housing" | "infrastructure" | "marketing" | "office" | "other" | "saas" | "transit"yesExpense category. Accepts a key or a Thai/English label and stores the key. ai = ค่าสมาชิก AI (AI Subscriptions); capital_deploy = ลงทุนในธุรกิจ (Deploy Capital to Business); connectivity = อินเทอร์เน็ตและมือถือ (Internet & Mobile); dev_tool = เครื่องมือนักพัฒนาและ API (Developer Tools & APIs); entertainment = ค่าสมาชิกและค่าใช้จ่ายในชีวิต (Subscriptions & Living); family = ครอบครัวและค่าใช้จ่ายส่วนตัว (Family & Personal); food = อาหาร (Food & Dining); groceries = ของชำและของใช้ในบ้าน (Groceries & Household); healthcare = สุขภาพ (Healthcare & Wellness); housing = ที่อยู่อาศัยและค่าเช่า (Housing & Rent); infrastructure = โฮสติ้งและโครงสร้างพื้นฐาน (Hosting & Infrastructure); marketing = การตลาดและการขาย (Marketing & Sales); office = ออฟฟิศและพื้นที่ทำงาน (Office & Workspace); other = อื่น ๆ (Other); saas = SaaS และเครื่องมือทำงาน (SaaS & Productivity); transit = เดินทาง (Transit & Transport)
amountnumberyes
cycle"weekly" | "monthly" | "quarterly" | "semi-annual" | "yearly" | "one_time"noHow often it repeats. An expense defaults to one_time (one receipt, dated by asOf, or today); an income or a liability defaults to monthly. one_time is counted only in startMonth; every other value repeats from startMonth on its own schedule.
dayOfMonthintegernoDay of the month the cycle falls on. For cycle: "one_time" this is the date of the receipt; it defaults from a day-precision asOf, otherwise the 1st.
startMonthstringno
endMonthstringno
paidFromAssetIdstringno
paidFromLiabilityIdstringno
assetIdstringno
incomeIdstringno
activebooleanno
notesstringno
imageUrlstringno
detailsmap of anyno

Responses

  • 201 — Expense created. Expense
  • 400 — Validation error. Error
  • 401 — Missing or invalid credential (session token or API key; only when auth is configured). Error
  • 404 — Record not found. Error
  • 409 — Version conflict or duplicate id. Error
curl -X POST "$API_URL/api/v1/accounting/expenses" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ ... }'

Get an expense

GET /api/v1/accounting/expenses/{id}

Parameters

NameInTypeRequiredDescription
idpathstringyes

Responses

  • 200 — The expense. Expense
  • 401 — Missing or invalid credential (session token or API key; only when auth is configured). Error
  • 404 — Record not found. Error
curl "$API_URL/api/v1/accounting/expenses/:id" \
  -H "Authorization: Bearer $TOKEN"

Update an expense

PATCH /api/v1/accounting/expenses/{id}

Partial update. details merges shallowly onto the stored details, so a patch for one key keeps the rest.

Parameters

NameInTypeRequiredDescription
idpathstringyes

Request body (application/json)

Type: object

FieldTypeRequiredDescription
versionintegernoStored version the caller last read; a mismatch returns 409.
asOfstringnoClient’s current month or day. For cycle: "one_time", a day-precision value such as 2026-10-26 is the date of the receipt (it sets dayOfMonth); a month-only value lands on the 1st. Otherwise the default month for startMonth.
namestringno
category"ai" | "capital_deploy" | "connectivity" | "dev_tool" | "entertainment" | "family" | "food" | "groceries" | "healthcare" | "housing" | "infrastructure" | "marketing" | "office" | "other" | "saas" | "transit"noExpense category. Accepts a key or a Thai/English label and stores the key. ai = ค่าสมาชิก AI (AI Subscriptions); capital_deploy = ลงทุนในธุรกิจ (Deploy Capital to Business); connectivity = อินเทอร์เน็ตและมือถือ (Internet & Mobile); dev_tool = เครื่องมือนักพัฒนาและ API (Developer Tools & APIs); entertainment = ค่าสมาชิกและค่าใช้จ่ายในชีวิต (Subscriptions & Living); family = ครอบครัวและค่าใช้จ่ายส่วนตัว (Family & Personal); food = อาหาร (Food & Dining); groceries = ของชำและของใช้ในบ้าน (Groceries & Household); healthcare = สุขภาพ (Healthcare & Wellness); housing = ที่อยู่อาศัยและค่าเช่า (Housing & Rent); infrastructure = โฮสติ้งและโครงสร้างพื้นฐาน (Hosting & Infrastructure); marketing = การตลาดและการขาย (Marketing & Sales); office = ออฟฟิศและพื้นที่ทำงาน (Office & Workspace); other = อื่น ๆ (Other); saas = SaaS และเครื่องมือทำงาน (SaaS & Productivity); transit = เดินทาง (Transit & Transport)
amountnumberno
cycle"weekly" | "monthly" | "quarterly" | "semi-annual" | "yearly" | "one_time" | nullno
dayOfMonthinteger | nullno
startMonthstring | nullno
endMonthstring | nullno
paidFromAssetIdstring | nullno
paidFromLiabilityIdstring | nullno
assetIdstring | nullno
incomeIdstring | nullno
activeboolean | nullno
notesstring | nullno
imageUrlstring | nullno
detailsmap of any | nullno

Responses

  • 200 — Expense updated. Expense
  • 400 — Validation error. Error
  • 401 — Missing or invalid credential (session token or API key; only when auth is configured). Error
  • 404 — Record not found. Error
  • 409 — Version conflict or duplicate id. Error
curl -X PATCH "$API_URL/api/v1/accounting/expenses/:id" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ ... }'

Delete an expense

DELETE /api/v1/accounting/expenses/{id}

Parameters

NameInTypeRequiredDescription
idpathstringyes

Responses

  • 200 — Expense deleted. Ok
  • 400 — Validation error. Error
  • 401 — Missing or invalid credential (session token or API key; only when auth is configured). Error
  • 404 — Record not found. Error
  • 409 — Version conflict or duplicate id. Error
curl -X DELETE "$API_URL/api/v1/accounting/expenses/:id" \
  -H "Authorization: Bearer $TOKEN"

List liabilities

GET /api/v1/accounting/liabilities

Parameters

NameInTypeRequiredDescription
entityIdquerystringno
kindquery"loan" | "revolving" | "other"no

Responses

  • 200 — Liabilities. Liability[]
  • 400 — Validation Error object
  • 401 — Missing or invalid credential (session token or API key; only when auth is configured). Error
curl "$API_URL/api/v1/accounting/liabilities" \
  -H "Authorization: Bearer $TOKEN"

Create a liability

POST /api/v1/accounting/liabilities

Body discriminated by kind. A loan without amount is paid at its level payment, calculateLoanPayment(principal, annualRate, termMonths), and its payments start in the origination month unless startMonth is given.

Request body (application/json)

Type: object | object | object

Responses

  • 201 — Liability created. Liability
  • 400 — Validation error. Error
  • 401 — Missing or invalid credential (session token or API key; only when auth is configured). Error
  • 404 — Record not found. Error
  • 409 — Version conflict or duplicate id. Error
curl -X POST "$API_URL/api/v1/accounting/liabilities" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ ... }'

Get a liability

GET /api/v1/accounting/liabilities/{id}

Parameters

NameInTypeRequiredDescription
idpathstringyes

Responses

  • 200 — The liability. Liability
  • 401 — Missing or invalid credential (session token or API key; only when auth is configured). Error
  • 404 — Record not found. Error
curl "$API_URL/api/v1/accounting/liabilities/:id" \
  -H "Authorization: Bearer $TOKEN"

Update a liability

PATCH /api/v1/accounting/liabilities/{id}

Partial update. loan and revolving merge shallowly onto the stored details.

Parameters

NameInTypeRequiredDescription
idpathstringyes

Request body (application/json)

Type: object

FieldTypeRequiredDescription
versionintegernoStored version the caller last read; a mismatch returns 409.
namestringno
categorystringno
cycle"weekly" | "monthly" | "quarterly" | "semi-annual" | "yearly" | "one_time" | nullno
dayOfMonthinteger | nullno
startMonthstring | nullno
endMonthstring | nullno
paidFromAssetIdstring | nullno
activeboolean | nullno
notesstring | nullno
imageUrlstring | nullno
detailsmap of any | nullno
amountnumberno
loanobjectnoMerged shallowly onto the stored loan details.
loan.principalnumberno
loan.annualRatenumbernoDefaults to 0 (0% installment plan).
loan.termMonthsintegerno
loan.originatedOnstringno
loan.financedAssetIdstringno
loan.proceedsAssetIdstringno
revolvingobjectnoMerged shallowly onto the stored revolving details.
revolving.creditLimitnumberno
revolving.balancenumbernoDefaults to 0.
revolving.balanceAsOfstringnoDefaults to the start month.
revolving.annualRatenumberno

Responses

  • 200 — Liability updated. Liability
  • 400 — Validation error. Error
  • 401 — Missing or invalid credential (session token or API key; only when auth is configured). Error
  • 404 — Record not found. Error
  • 409 — Version conflict or duplicate id. Error
curl -X PATCH "$API_URL/api/v1/accounting/liabilities/:id" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ ... }'

Delete a liability

DELETE /api/v1/accounting/liabilities/{id}

Parameters

NameInTypeRequiredDescription
idpathstringyes

Responses

  • 200 — Liability deleted. Ok
  • 400 — Validation error. Error
  • 401 — Missing or invalid credential (session token or API key; only when auth is configured). Error
  • 404 — Record not found. Error
  • 409 — Version conflict or duplicate id. Error
curl -X DELETE "$API_URL/api/v1/accounting/liabilities/:id" \
  -H "Authorization: Bearer $TOKEN"

Get a liability’s month-by-month schedule

GET /api/v1/accounting/liabilities/{id}/schedule

Loans: payments, interest and principal per month, including extra-payment transfers. Revolving: opening balance, interest, card charges and payments per month. Liabilities of kind other have no schedule (400).

Parameters

NameInTypeRequiredDescription
throughquerystringnoLast month YYYY-MM. Loans default to the payoff month or the end of the term, whichever comes first (capped at 600 months). Revolving balances default to the current UTC month.
idpathstringyes

Responses

  • 200 — Loan or revolving schedule. LoanSchedule | RevolvingSchedule
  • 400 — Validation error, or the liability has no schedule. Error
  • 401 — Missing or invalid credential (session token or API key; only when auth is configured). Error
  • 404 — Liability not found. Error
curl "$API_URL/api/v1/accounting/liabilities/:id/schedule" \
  -H "Authorization: Bearer $TOKEN"

List transfers

GET /api/v1/accounting/transfers

Responses

  • 200 — Transfers. Transfer[]
  • 401 — Missing or invalid credential (session token or API key; only when auth is configured). Error
curl "$API_URL/api/v1/accounting/transfers" \
  -H "Authorization: Bearer $TOKEN"

Create a transfer

POST /api/v1/accounting/transfers

Source: fromAssetId or fromEntityId (its default cash asset). Destination: exactly one of toAssetId, toEntityId (its default cash asset) or toLiabilityId.

Request body (application/json)

Type: object

FieldTypeRequiredDescription
idstringnoOptional client-generated UUID used as the record id. Repeating a create with the same id must not add a second record: the MCP create tools return the stored record with deduplicated: true, and the REST routes answer 409 DUPLICATE.
amountnumberyes
datestringyes
cycle"one_time" | "monthly"no
notestringno
fromAssetIdstringno
fromEntityIdstringnoResolves to the entity’s default cash asset.
toAssetIdstringno
toEntityIdstringnoResolves to the entity’s default cash asset.
toLiabilityIdstringno

Responses

  • 201 — Transfer created. Transfer
  • 400 — Validation error. Error
  • 401 — Missing or invalid credential (session token or API key; only when auth is configured). Error
  • 404 — Record not found. Error
  • 409 — Version conflict or duplicate id. Error
curl -X POST "$API_URL/api/v1/accounting/transfers" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ ... }'

Get a transfer

GET /api/v1/accounting/transfers/{id}

Parameters

NameInTypeRequiredDescription
idpathstringyes

Responses

  • 200 — The transfer. Transfer
  • 401 — Missing or invalid credential (session token or API key; only when auth is configured). Error
  • 404 — Record not found. Error
curl "$API_URL/api/v1/accounting/transfers/:id" \
  -H "Authorization: Bearer $TOKEN"

Update a transfer

PATCH /api/v1/accounting/transfers/{id}

Partial update. Name a new source or destination to re-resolve that side.

Parameters

NameInTypeRequiredDescription
idpathstringyes

Request body (application/json)

Type: object

FieldTypeRequiredDescription
versionintegernoStored version the caller last read; a mismatch returns 409.
amountnumberno
datestringno
cycle"one_time" | "monthly"no
notestringno
fromAssetIdstringno
fromEntityIdstringnoResolves to the entity’s default cash asset.
toAssetIdstringno
toEntityIdstringnoResolves to the entity’s default cash asset.
toLiabilityIdstringno

Responses

  • 200 — Transfer updated. Transfer
  • 400 — Validation error. Error
  • 401 — Missing or invalid credential (session token or API key; only when auth is configured). Error
  • 404 — Record not found. Error
  • 409 — Version conflict or duplicate id. Error
curl -X PATCH "$API_URL/api/v1/accounting/transfers/:id" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ ... }'

Delete a transfer

DELETE /api/v1/accounting/transfers/{id}

Parameters

NameInTypeRequiredDescription
idpathstringyes

Responses

  • 200 — Transfer deleted. Ok
  • 400 — Validation error. Error
  • 401 — Missing or invalid credential (session token or API key; only when auth is configured). Error
  • 404 — Record not found. Error
  • 409 — Version conflict or duplicate id. Error
curl -X DELETE "$API_URL/api/v1/accounting/transfers/:id" \
  -H "Authorization: Bearer $TOKEN"

Get wealth metrics and balance sheet per entity and consolidated

GET /api/v1/accounting/summary

Per entity: wealth metrics and balance sheet at month. Consolidated: metrics plus the balance sheet summed over all entities.

Parameters

NameInTypeRequiredDescription
monthquerystringyesYYYY-MM.
asOfquerystringnoToday (YYYY-MM-DD); current values are as of this day when inside month.

Responses

  • 200 — Summary for the month. Summary
  • 400 — Validation error. Error
  • 401 — Missing or invalid credential (session token or API key; only when auth is configured). Error
curl "$API_URL/api/v1/accounting/summary" \
  -H "Authorization: Bearer $TOKEN"

Get computed monthly ledger

GET /api/v1/accounting/ledger/{yearMonth}

Parameters

NameInTypeRequiredDescription
entityIdquerystringno
yearMonthpathstringyes

Responses

  • 200 — Monthly ledger. MonthlyLedger
  • 400 — Validation Error object
  • 401 — Missing or invalid credential (session token or API key; only when auth is configured). Error
  • 404 — Entity not found. Error
curl "$API_URL/api/v1/accounting/ledger/:yearMonth" \
  -H "Authorization: Bearer $TOKEN"

Get the cash-flow feed for a month

GET /api/v1/accounting/cash-flows

Dated money movements of one entity (default: personal) for one month. direction filters items; totals (moneyIn, moneyOut, spending) always cover every item.

Parameters

NameInTypeRequiredDescription
monthquerystringyesYYYY-MM.
entityIdquerystringnoDefaults to the personal entity.
directionquery"in" | "out"noFilters items only; totals always cover every item.
includeDepreciationquery"true" | "false"noAdds non-cash depreciation items. Defaults to false.

Responses

  • 200 — Cash-flow feed and totals. CashFlowsResponse
  • 400 — Validation error. Error
  • 401 — Missing or invalid credential (session token or API key; only when auth is configured). Error
  • 404 — Entity not found. Error
curl "$API_URL/api/v1/accounting/cash-flows" \
  -H "Authorization: Bearer $TOKEN"

Get treasury balance per month around a centre month

GET /api/v1/accounting/projection

Parameters

NameInTypeRequiredDescription
entityIdquerystringnoDefaults to the personal entity.
monthquerystringnoCentre month YYYY-MM. Defaults to the UTC month.
pastMonthsqueryintegerno
futureMonthsqueryintegerno
asOfquerystringno

Responses

  • 200 — Projection points and waterfall figures. Projection
  • 400 — Validation error. Error
  • 401 — Missing or invalid credential (session token or API key; only when auth is configured). Error
  • 404 — Entity not found. Error
curl "$API_URL/api/v1/accounting/projection" \
  -H "Authorization: Bearer $TOKEN"

Schemas

Entity

A personal or business entity that owns money flows.

FieldTypeRequiredDescription
idstringyes
namestringyes
type"personal" | "business"yes
currencystringyesISO currency code, typically THB or USD.
targetSafetyBuffernumberno
activebooleanyes
notesstringno
imageUrlstringno
versionintegeryesStarts at 1; every update bumps it. PATCH may send it back to detect conflicts.
createdAtstringyesISO timestamp.
updatedAtstringyesISO timestamp.

Error

FieldTypeRequiredDescription
errorstringyes

Ok

FieldTypeRequiredDescription
oktrueyes

Asset

An asset, discriminated by kind.

Type: CashAsset | FixedAsset | InvestmentAsset

Income

An income stream.

FieldTypeRequiredDescription
idstringyes
entityIdstringyes
kind"employment" | "business" | "investment" | "other"yes
categorystringyessalary, bonus, freelance, sales, dividend, interest, rent…
namestringyes
amountnumberyes
cycle"weekly" | "monthly" | "quarterly" | "semi-annual" | "yearly" | "one_time"yes
dayOfMonthintegernoDay the money moves; absent = the flow type’s default day.
startMonthstringyesYYYY-MM. First month the flow happens.
endMonthstringnoYYYY-MM. Last month; absent = open-ended.
taxCategory"40_1" | "40_2" | "40_3" | "40_4" | "40_5" | "40_6" | "40_7" | "40_8"no
depositAssetIdstringnoCash asset the income lands in; absent = the default cash asset.
sourceAssetIdstringnoAsset that generates it. Investment income only.
employmentobjectnoPresent only when kind is employment.
employment.employerstringno
employment.titlestringno
activebooleanyes
notesstringno
imageUrlstringno
detailsmap of anyyesDisplay-only extras the engine never reads.
versionintegeryesStarts at 1; every update bumps it. PATCH may send it back to detect conflicts.
createdAtstringyesISO timestamp.
updatedAtstringyesISO timestamp.

Expense

A recurring or one-time cost.

FieldTypeRequiredDescription
idstringyes
entityIdstringyes
namestringyes
categorystringyes
amountnumberyes
cycle"weekly" | "monthly" | "quarterly" | "semi-annual" | "yearly" | "one_time"yes
dayOfMonthintegernoDay the money moves; absent = the flow type’s default day.
startMonthstringyesYYYY-MM. First month the flow happens.
endMonthstringnoYYYY-MM. Last month; absent = open-ended.
paidFromAssetIdstringno
paidFromLiabilityIdstringnoRevolving liability (credit card) it is charged to.
assetIdstringnoAsset this is a cost of owning.
incomeIdstringnoIncome this is a cost of earning.
activebooleanyes
notesstringno
imageUrlstringno
detailsmap of anyyesDisplay-only extras the engine never reads.
versionintegeryesStarts at 1; every update bumps it. PATCH may send it back to detect conflicts.
createdAtstringyesISO timestamp.
updatedAtstringyesISO timestamp.

Liability

A debt. The schedule is the planned payment.

FieldTypeRequiredDescription
idstringyes
entityIdstringyes
kind"loan" | "revolving" | "other"yes
namestringyes
categorystringyes
amountnumberyes
cycle"weekly" | "monthly" | "quarterly" | "semi-annual" | "yearly" | "one_time"yes
dayOfMonthintegernoDay the money moves; absent = the flow type’s default day.
startMonthstringyesYYYY-MM. First month the flow happens.
endMonthstringnoYYYY-MM. Last month; absent = open-ended.
paidFromAssetIdstringno
loanLoanDetailsno
revolvingRevolvingDetailsno
activebooleanyes
notesstringno
imageUrlstringno
detailsmap of anyyesDisplay-only extras the engine never reads.
versionintegeryesStarts at 1; every update bumps it. PATCH may send it back to detect conflicts.
createdAtstringyesISO timestamp.
updatedAtstringyesISO timestamp.

LoanSchedule

Month-by-month loan schedule.

FieldTypeRequiredDescription
liabilityIdstringyes
kind"loan"yes
entriesLoanScheduleEntry[]yes

RevolvingSchedule

Month-by-month revolving balance.

FieldTypeRequiredDescription
liabilityIdstringyes
kind"revolving"yes
entriesRevolvingScheduleEntry[]yes

Transfer

Money moved from an asset to an asset, or onto a liability.

FieldTypeRequiredDescription
idstringyes
amountnumberyes
datestringyesYYYY-MM-DD or YYYY-MM.
cycle"one_time" | "monthly"yes
notestringyes
fromAssetIdstringyes
toAssetIdstringno
toLiabilityIdstringno
versionintegeryesStarts at 1; every update bumps it. PATCH may send it back to detect conflicts.
createdAtstringyesISO timestamp.
updatedAtstringyesISO timestamp.

Summary

Wealth metrics per entity and consolidated, for one month.

FieldTypeRequiredDescription
yearMonthstringyes
asOfstringno
entitiesobject[]yes
entities[].entityIdstringyes
entities[].metricsobjectyes
entities[].metrics.cashAssetsValuenumberyes
entities[].metrics.gearAssetsValuenumberyes
entities[].metrics.totalAssetsValuenumberyes
entities[].metrics.currentLiquidnumberyes
entities[].metrics.eomLiquidnumberyes
entities[].metrics.currentWealthnumberyes
entities[].metrics.eomWealthnumberyes
entities[].metrics.liquidPctnumberyes
entities[].metrics.gearPctnumberyes
entities[].metrics.totalIncomenumberyes
entities[].metrics.totalExpensenumberyes
entities[].metrics.liabilityMonthlynumberyes
entities[].metrics.liabPctnumberyes
entities[].metrics.runwayMonthsnumber | nullyes
entities[].metrics.isDefaultAlivebooleanyes
entities[].balanceSheetBalanceSheetyes
consolidatedobjectyes
consolidated.totalTreasurynumberyes
consolidated.totalEomTreasurynumberyes
consolidated.personalCashnumberyes
consolidated.businessCashnumberyes
consolidated.balanceSheetBalanceSheetyes

MonthlyLedger

Computed cash ledger for one entity and month.

FieldTypeRequiredDescription
yearMonthstringyes
summaryobjectyes
summary.entityIdstringno
summary.yearMonthstringno
summary.startingTreasurynumberyes
summary.endingTreasurynumberyes
summary.totalInflownumberyes
summary.totalCashOutflownumberyes
summary.totalDepreciationnumberyes
summary.netCashFlownumberyes
summary.runwayMonthsnumber | nullno
summary.isDefaultAlivebooleanno
actionItemsobject[]yes
actionItems[].idstringyes
actionItems[].entityIdstringno
actionItems[].yearMonthstringno
actionItems[].titlestringyes
actionItems[].datestringyes
actionItems[].amountnumberyes
actionItems[].type"subscription" | "depreciation" | "revenue" | "capital_in" | "capital_out" | "inflow" | "outflow"yes
actionItems[].categorystringno
actionItems[].referencestringno

CashFlowsResponse

Cash-flow feed of one entity for one month, with totals over all items.

FieldTypeRequiredDescription
yearMonthstringyes
entityIdstringyes
itemsCashFlowItem[]yes
totalsobjectyes
totals.moneyInnumberyesCash in, from cash items only.
totals.moneyOutnumberyesCash out, from cash items only.
totals.spendingnumberyesSum of spendingAmount over every item.
spendingByCategoryobject[]yesSpending by expense category for the month, over the unfiltered feed. Always contains “uncategorised”; the buckets sum to totals.spending. Answer “how much on X this month” from here, never by grouping items.
spendingByCategory[].categorystringyesAn expense key, or “uncategorised” for spending without one.
spendingByCategory[].spendingnumberyes
spendingByCategory[].countintegeryesItems in the bucket.
spendingByCategory[].sharenumberyesspending / totals.spending, 4 dp; 0 when nothing was spent.

Projection

Treasury balance per month around a centre month.

FieldTypeRequiredDescription
pointsobject[]yes
points[].offsetintegeryes
points[].yearMonthstringyes
points[].balancenumberyes
totalIncomenumberyes
totalExpensenumberyes
liabilityMonthlynumberyes
projectedNetnumberyes

CashAsset

Cash and cash equivalents: bank accounts, e-wallets, cash on hand.

FieldTypeRequiredDescription
idstringyes
entityIdstringyesOwning Entity.id.
namestringyes
categorystringyesFree-form sub-type: bank, e_wallet, laptop, vehicle, property, stock…
activebooleanyes
notesstringno
imageUrlstringno
detailsmap of anyyesDisplay-only extras the engine never reads.
kind"cash"yes
balancenumberyesBalance at the start of balanceAsOf.
balanceAsOfstringyesYYYY-MM, or YYYY-MM-DD for a balance recorded mid-month.
currencystringyes
isDefaultbooleanyesWhere unlinked money of the entity lands. One per entity.
versionintegeryesStarts at 1; every update bumps it. PATCH may send it back to detect conflicts.
createdAtstringyesISO timestamp.
updatedAtstringyesISO timestamp.

FixedAsset

PP&E bought once and depreciated over its useful life.

FieldTypeRequiredDescription
idstringyes
entityIdstringyesOwning Entity.id.
namestringyes
categorystringyesFree-form sub-type: bank, e_wallet, laptop, vehicle, property, stock…
activebooleanyes
notesstringno
imageUrlstringno
detailsmap of anyyesDisplay-only extras the engine never reads.
kind"fixed"yes
costnumberyes
acquiredOnstringyesYYYY-MM or YYYY-MM-DD.
depreciationMethod"straight_line" | "none"yes
usefulLifeMonthsintegernoRequired unless depreciationMethod is none.
salvageValuenumberyes
versionintegeryesStarts at 1; every update bumps it. PATCH may send it back to detect conflicts.
createdAtstringyesISO timestamp.
updatedAtstringyesISO timestamp.

InvestmentAsset

Valued at market, grown by an expected return, never depreciated.

FieldTypeRequiredDescription
idstringyes
entityIdstringyesOwning Entity.id.
namestringyes
categorystringyesFree-form sub-type: bank, e_wallet, laptop, vehicle, property, stock…
activebooleanyes
notesstringno
imageUrlstringno
detailsmap of anyyesDisplay-only extras the engine never reads.
kind"investment"yes
instrumentstringyes
symbolstringno
unitsnumberno
costBasisnumberyes
marketValuenumberyes
valuedAsOfstringyesYYYY-MM.
expectedAnnualReturnnumbernoYearly return as a fraction (0.07 = 7%).
currencystringyes
versionintegeryesStarts at 1; every update bumps it. PATCH may send it back to detect conflicts.
createdAtstringyesISO timestamp.
updatedAtstringyesISO timestamp.

LoanDetails

Amortizing loan terms.

FieldTypeRequiredDescription
principalnumberyes
annualRatenumberyesYearly interest rate as a fraction (0.065 = 6.5%).
termMonthsintegeryes
originatedOnstringyesYYYY-MM or YYYY-MM-DD.
financedAssetIdstringno
proceedsAssetIdstringno

RevolvingDetails

Revolving credit: a card or credit line.

FieldTypeRequiredDescription
creditLimitnumberno
balancenumberyes
balanceAsOfstringyesYYYY-MM.
annualRatenumberno

LoanScheduleEntry

One month of a loan.

FieldTypeRequiredDescription
yearMonthstringyes
openingnumberyes
interestnumberyes
paymentnumberyesScheduled payment actually made, capped at what is owed.
extranumberyesExtra payments applied, capped at what is owed after payment.
principalnumberyesPrincipal repaid; negative when the balance grows.
closingnumberyes

RevolvingScheduleEntry

One month of a revolving balance.

FieldTypeRequiredDescription
yearMonthstringyes
openingnumberyes
interestnumberyes
chargesnumberyesMonthly-equivalent card charges that month.
paymentnumberyesScheduled payment made, capped at what is owed.
extranumberyesTransfers into the card applied that month, capped at what is still owed.
paymentsnumberyespayment + extra.
closingnumberyes

BalanceSheet

Position at the end of one month.

FieldTypeRequiredDescription
cashnumberyesEnd-of-month treasury of the cash wallets.
fixedAssetsnumberyesRemaining book value of fixed (non-cash, non-investment) assets.
investmentsnumberyesValue of investment assets.
totalAssetsnumberyescash + fixedAssets + investments.
debtnumberyesLoan and revolving balances owed.
netWorthnumberyestotalAssets - debt.

CashFlowItem

One dated money movement in the cash-flow feed.

FieldTypeRequiredDescription
idstringyesUnique within the month’s feed.
sourceType"income" | "expense" | "liability" | "transfer" | "asset" | "account"yes
sourceIdstringyesThe record to open when tapped.
flowType"income" | "expense" | "debt_payment" | "asset_purchase" | "investment" | "transfer" | "loan_proceeds" | "depreciation"yes
direction"in" | "out"yes
datestringyesYYYY-MM-DD.
namestringyes
amountnumberyes
isCashbooleanyesFalse for card charges and depreciation: they move no cash.
spendingAmountnumberyesThe part of the amount that counts as spending.
categorystringnoOn an expense item, the canonical expense category (see spendingByCategory). On other items, the ledger flow class (revenue, salary, transfer, …).
cashAssetIdstringno
chargedToLiabilityIdstringnoRevolving liability a card charge lands on.
interestnumbernoLoan payments only.
principalnumbernoLoan payments only.