API reference

Rudopo API · version 1.0.0 · base URL https://rudopo.app/api/v1

Generated from the OpenAPI description that ships with the code. Every request needs Authorization: Bearer rudopo_pat_YOUR_TOKEN.

Endpoints

get/budgets

List budgets

Every budget this token may reach. A token narrowed to specific budgets sees only those.

Responses: 200 OK · 400 A parameter is missing or malformed · 401 No token, or the token is invalid, revoked or expired · 403 About the TOKEN: it lacks the scope, or is not scoped to that budget · 404 Not reachable by this token. A nonexistent id and another owner's id answer identically · 429 Rate limited — see Retry-After · 500 Something went wrong. The body never names internals

get/accounts

List accounts

ParameterInTypeRequiredNotes
budget_idquerystringyesThe budget to read. Required on every budget-scoped resource.

Responses: 200 OK · 400 A parameter is missing or malformed · 401 No token, or the token is invalid, revoked or expired · 403 About the TOKEN: it lacks the scope, or is not scoped to that budget · 404 Not reachable by this token. A nonexistent id and another owner's id answer identically · 429 Rate limited — see Retry-After · 500 Something went wrong. The body never names internals

get/transactions

List transactions

Newest first. Filters run server-side, so the page limit applies to the FILTERED set.

ParameterInTypeRequiredNotes
budget_idquerystringyesThe budget to read. Required on every budget-scoped resource.
account_idquerystringno
category_idquerystringno
start_datequerystringnoYYYY-MM-DD, inclusive
end_datequerystringnoYYYY-MM-DD, inclusive
searchquerystringnoMatches payee, memo and category. 200 characters maximum.
uncategorizedquerybooleanno
unclearedquerybooleanno
limitqueryintegerno1–1000.
offsetqueryintegerno
cursorquerystringnoPage by position instead of by offset: `start` for the first page, then each answer's `next_cursor`. Holds still while rows are written; a cursor works only with the token and the filters it came from.

Responses: 200 OK · 400 A parameter is missing or malformed · 401 No token, or the token is invalid, revoked or expired · 403 About the TOKEN: it lacks the scope, or is not scoped to that budget · 404 Not reachable by this token. A nonexistent id and another owner's id answer identically · 429 Rate limited — see Retry-After · 500 Something went wrong. The body never names internals

post/transactions

Add a transaction, a transfer or a split

ParameterInTypeRequiredNotes
budget_idquerystringyesThe budget to read. Required on every budget-scoped resource.
dry_runquerybooleannoAnswer with what this would do, and write nothing. Needs no Idempotency-Key and spends none.
Idempotency-KeyheaderstringyesOne value per intended change, the same one on a retry. A repeat replays the first answer; a different body is a 409.

Responses: 201 Written. With dry_run: what it would do, and nothing written · 202 Filed as a proposal in the person's review inbox. Nothing is written until they accept it · 400 A parameter is missing or malformed · 401 No token, or the token is invalid, revoked or expired · 402 This write needs an active subscription · 403 About the TOKEN: it lacks the scope, or is not scoped to that budget · 404 Not reachable by this token. A nonexistent id and another owner's id answer identically · 409 See `reason` · 429 Rate limited — see Retry-After · 500 Something went wrong. The body never names internals

post/transactions/batch

Add up to 50 transactions

Each row is its own write with its own outcome in `results`. Not atomic: a retry with the same key replays what landed and runs what did not.

ParameterInTypeRequiredNotes
budget_idquerystringyesThe budget to read. Required on every budget-scoped resource.
dry_runquerybooleannoAnswer with what this would do, and write nothing. Needs no Idempotency-Key and spends none.
Idempotency-KeyheaderstringyesOne value per intended change, the same one on a retry. A repeat replays the first answer; a different body is a 409.

Responses: 200 Written. With dry_run: what it would do, and nothing written · 202 Filed as a proposal in the person's review inbox. Nothing is written until they accept it · 400 A parameter is missing or malformed · 401 No token, or the token is invalid, revoked or expired · 402 This write needs an active subscription · 403 About the TOKEN: it lacks the scope, or is not scoped to that budget · 404 Not reachable by this token. A nonexistent id and another owner's id answer identically · 409 See `reason` · 429 Rate limited — see Retry-After · 500 Something went wrong. The body never names internals

patch/transactions/{id}

Edit a transaction

Send the `version` you read. An edit of a row that moved since is a 409 with reason `superseded`; of a reconciled row, reason `reconciled`. Editing a transfer leg carries its pair.

ParameterInTypeRequiredNotes
idpathstringyes
dry_runquerybooleannoAnswer with what this would do, and write nothing. Needs no Idempotency-Key and spends none.
Idempotency-KeyheaderstringyesOne value per intended change, the same one on a retry. A repeat replays the first answer; a different body is a 409.

Responses: 200 Written. With dry_run: what it would do, and nothing written · 202 Filed as a proposal in the person's review inbox. Nothing is written until they accept it · 400 A parameter is missing or malformed · 401 No token, or the token is invalid, revoked or expired · 402 This write needs an active subscription · 403 About the TOKEN: it lacks the scope, or is not scoped to that budget · 404 Not reachable by this token. A nonexistent id and another owner's id answer identically · 409 See `reason` · 429 Rate limited — see Retry-After · 500 Something went wrong. The body never names internals

delete/transactions/{id}

Delete a transaction

Needs the `write` scope. A transfer leg takes its pair with it, and the answer says so.

ParameterInTypeRequiredNotes
idpathstringyes
dry_runquerybooleannoAnswer with what this would do, and write nothing. Needs no Idempotency-Key and spends none.
Idempotency-KeyheaderstringnoOne value per intended change, the same one on a retry. A repeat replays the first answer; a different body is a 409.

Responses: 200 Written. With dry_run: what it would do, and nothing written · 202 Filed as a proposal in the person's review inbox. Nothing is written until they accept it · 400 A parameter is missing or malformed · 401 No token, or the token is invalid, revoked or expired · 402 This write needs an active subscription · 403 About the TOKEN: it lacks the scope, or is not scoped to that budget · 404 Not reachable by this token. A nonexistent id and another owner's id answer identically · 409 See `reason` · 429 Rate limited — see Retry-After · 500 Something went wrong. The body never names internals

post/transactions/{id}/labels

Put a label on a transaction

ParameterInTypeRequiredNotes
idpathstringyes
dry_runquerybooleannoAnswer with what this would do, and write nothing. Needs no Idempotency-Key and spends none.
Idempotency-KeyheaderstringyesOne value per intended change, the same one on a retry. A repeat replays the first answer; a different body is a 409.

Responses: 200 Written. With dry_run: what it would do, and nothing written · 202 Filed as a proposal in the person's review inbox. Nothing is written until they accept it · 400 A parameter is missing or malformed · 401 No token, or the token is invalid, revoked or expired · 402 This write needs an active subscription · 403 About the TOKEN: it lacks the scope, or is not scoped to that budget · 404 Not reachable by this token. A nonexistent id and another owner's id answer identically · 409 See `reason` · 429 Rate limited — see Retry-After · 500 Something went wrong. The body never names internals

delete/transactions/{id}/labels/{label_id}

Take a label off a transaction

ParameterInTypeRequiredNotes
idpathstringyes
label_idpathstringyes
dry_runquerybooleannoAnswer with what this would do, and write nothing. Needs no Idempotency-Key and spends none.
Idempotency-KeyheaderstringnoOne value per intended change, the same one on a retry. A repeat replays the first answer; a different body is a 409.

Responses: 200 Written. With dry_run: what it would do, and nothing written · 202 Filed as a proposal in the person's review inbox. Nothing is written until they accept it · 400 A parameter is missing or malformed · 401 No token, or the token is invalid, revoked or expired · 402 This write needs an active subscription · 403 About the TOKEN: it lacks the scope, or is not scoped to that budget · 404 Not reachable by this token. A nonexistent id and another owner's id answer identically · 409 See `reason` · 429 Rate limited — see Retry-After · 500 Something went wrong. The body never names internals

get/categories

List category groups with their categories

ParameterInTypeRequiredNotes
budget_idquerystringyesThe budget to read. Required on every budget-scoped resource.
include_hiddenquerybooleanno
limitqueryintegerno1–500.
offsetqueryintegerno

Responses: 200 OK · 400 A parameter is missing or malformed · 401 No token, or the token is invalid, revoked or expired · 403 About the TOKEN: it lacks the scope, or is not scoped to that budget · 404 Not reachable by this token. A nonexistent id and another owner's id answer identically · 429 Rate limited — see Retry-After · 500 Something went wrong. The body never names internals

post/categories

Add a category

ParameterInTypeRequiredNotes
budget_idquerystringyesThe budget to read. Required on every budget-scoped resource.
dry_runquerybooleannoAnswer with what this would do, and write nothing. Needs no Idempotency-Key and spends none.
Idempotency-KeyheaderstringyesOne value per intended change, the same one on a retry. A repeat replays the first answer; a different body is a 409.

Responses: 201 Written. With dry_run: what it would do, and nothing written · 202 Filed as a proposal in the person's review inbox. Nothing is written until they accept it · 400 A parameter is missing or malformed · 401 No token, or the token is invalid, revoked or expired · 402 This write needs an active subscription · 403 About the TOKEN: it lacks the scope, or is not scoped to that budget · 404 Not reachable by this token. A nonexistent id and another owner's id answer identically · 409 See `reason` · 429 Rate limited — see Retry-After · 500 Something went wrong. The body never names internals

patch/categories/{id}

Edit a category

ParameterInTypeRequiredNotes
idpathstringyes
budget_idquerystringyesThe budget to read. Required on every budget-scoped resource.
dry_runquerybooleannoAnswer with what this would do, and write nothing. Needs no Idempotency-Key and spends none.
Idempotency-KeyheaderstringyesOne value per intended change, the same one on a retry. A repeat replays the first answer; a different body is a 409.

Responses: 200 Written. With dry_run: what it would do, and nothing written · 202 Filed as a proposal in the person's review inbox. Nothing is written until they accept it · 400 A parameter is missing or malformed · 401 No token, or the token is invalid, revoked or expired · 402 This write needs an active subscription · 403 About the TOKEN: it lacks the scope, or is not scoped to that budget · 404 Not reachable by this token. A nonexistent id and another owner's id answer identically · 409 See `reason` · 429 Rate limited — see Retry-After · 500 Something went wrong. The body never names internals

put/categories/{id}/target

Set a category's target

ParameterInTypeRequiredNotes
idpathstringyes
budget_idquerystringyesThe budget to read. Required on every budget-scoped resource.
dry_runquerybooleannoAnswer with what this would do, and write nothing. Needs no Idempotency-Key and spends none.
Idempotency-KeyheaderstringyesOne value per intended change, the same one on a retry. A repeat replays the first answer; a different body is a 409.

Responses: 200 Written. With dry_run: what it would do, and nothing written · 202 Filed as a proposal in the person's review inbox. Nothing is written until they accept it · 400 A parameter is missing or malformed · 401 No token, or the token is invalid, revoked or expired · 402 This write needs an active subscription · 403 About the TOKEN: it lacks the scope, or is not scoped to that budget · 404 Not reachable by this token. A nonexistent id and another owner's id answer identically · 409 See `reason` · 429 Rate limited — see Retry-After · 500 Something went wrong. The body never names internals

delete/categories/{id}/target

Remove a category's target

ParameterInTypeRequiredNotes
idpathstringyes
budget_idquerystringyesThe budget to read. Required on every budget-scoped resource.
dry_runquerybooleannoAnswer with what this would do, and write nothing. Needs no Idempotency-Key and spends none.
Idempotency-KeyheaderstringnoOne value per intended change, the same one on a retry. A repeat replays the first answer; a different body is a 409.

Responses: 200 Written. With dry_run: what it would do, and nothing written · 202 Filed as a proposal in the person's review inbox. Nothing is written until they accept it · 400 A parameter is missing or malformed · 401 No token, or the token is invalid, revoked or expired · 402 This write needs an active subscription · 403 About the TOKEN: it lacks the scope, or is not scoped to that budget · 404 Not reachable by this token. A nonexistent id and another owner's id answer identically · 409 See `reason` · 429 Rate limited — see Retry-After · 500 Something went wrong. The body never names internals

get/payees

List payees

ParameterInTypeRequiredNotes
budget_idquerystringyesThe budget to read. Required on every budget-scoped resource.
limitqueryintegerno1–500.
offsetqueryintegerno

Responses: 200 OK · 400 A parameter is missing or malformed · 401 No token, or the token is invalid, revoked or expired · 403 About the TOKEN: it lacks the scope, or is not scoped to that budget · 404 Not reachable by this token. A nonexistent id and another owner's id answer identically · 429 Rate limited — see Retry-After · 500 Something went wrong. The body never names internals

post/payees

Add a payee

ParameterInTypeRequiredNotes
budget_idquerystringyesThe budget to read. Required on every budget-scoped resource.
dry_runquerybooleannoAnswer with what this would do, and write nothing. Needs no Idempotency-Key and spends none.
Idempotency-KeyheaderstringyesOne value per intended change, the same one on a retry. A repeat replays the first answer; a different body is a 409.

Responses: 201 Written. With dry_run: what it would do, and nothing written · 202 Filed as a proposal in the person's review inbox. Nothing is written until they accept it · 400 A parameter is missing or malformed · 401 No token, or the token is invalid, revoked or expired · 402 This write needs an active subscription · 403 About the TOKEN: it lacks the scope, or is not scoped to that budget · 404 Not reachable by this token. A nonexistent id and another owner's id answer identically · 409 See `reason` · 429 Rate limited — see Retry-After · 500 Something went wrong. The body never names internals

patch/payees/{id}

Rename a payee, on every row that carries it

ParameterInTypeRequiredNotes
idpathstringyes
budget_idquerystringyesThe budget to read. Required on every budget-scoped resource.
dry_runquerybooleannoAnswer with what this would do, and write nothing. Needs no Idempotency-Key and spends none.
Idempotency-KeyheaderstringyesOne value per intended change, the same one on a retry. A repeat replays the first answer; a different body is a 409.

Responses: 200 Written. With dry_run: what it would do, and nothing written · 202 Filed as a proposal in the person's review inbox. Nothing is written until they accept it · 400 A parameter is missing or malformed · 401 No token, or the token is invalid, revoked or expired · 402 This write needs an active subscription · 403 About the TOKEN: it lacks the scope, or is not scoped to that budget · 404 Not reachable by this token. A nonexistent id and another owner's id answer identically · 409 See `reason` · 429 Rate limited — see Retry-After · 500 Something went wrong. The body never names internals

get/labels

List labels

ParameterInTypeRequiredNotes
budget_idquerystringyesThe budget to read. Required on every budget-scoped resource.
limitqueryintegerno1–500.
offsetqueryintegerno

Responses: 200 OK · 400 A parameter is missing or malformed · 401 No token, or the token is invalid, revoked or expired · 403 About the TOKEN: it lacks the scope, or is not scoped to that budget · 404 Not reachable by this token. A nonexistent id and another owner's id answer identically · 429 Rate limited — see Retry-After · 500 Something went wrong. The body never names internals

get/months/{month}

Get one budget month

The envelope answer for a month: what is left to assign, what was assigned, what is overspent.

ParameterInTypeRequiredNotes
monthpathstringyesYYYY-MM
budget_idquerystringyesThe budget to read. Required on every budget-scoped resource.

Responses: 200 OK · 400 A parameter is missing or malformed · 401 No token, or the token is invalid, revoked or expired · 403 About the TOKEN: it lacks the scope, or is not scoped to that budget · 404 Not reachable by this token. A nonexistent id and another owner's id answer identically · 429 Rate limited — see Retry-After · 500 Something went wrong. The body never names internals

patch/months/{month}/categories/{id}

Set what is assigned to a category

ParameterInTypeRequiredNotes
monthpathstringyesYYYY-MM
idpathstringyes
budget_idquerystringyesThe budget to read. Required on every budget-scoped resource.
dry_runquerybooleannoAnswer with what this would do, and write nothing. Needs no Idempotency-Key and spends none.
Idempotency-KeyheaderstringyesOne value per intended change, the same one on a retry. A repeat replays the first answer; a different body is a 409.

Responses: 200 Written. With dry_run: what it would do, and nothing written · 202 Filed as a proposal in the person's review inbox. Nothing is written until they accept it · 400 A parameter is missing or malformed · 401 No token, or the token is invalid, revoked or expired · 402 This write needs an active subscription · 403 About the TOKEN: it lacks the scope, or is not scoped to that budget · 404 Not reachable by this token. A nonexistent id and another owner's id answer identically · 409 See `reason` · 429 Rate limited — see Retry-After · 500 Something went wrong. The body never names internals

post/months/{month}/moves

Move money between categories, or cover overspending

ParameterInTypeRequiredNotes
monthpathstringyesYYYY-MM
budget_idquerystringyesThe budget to read. Required on every budget-scoped resource.
dry_runquerybooleannoAnswer with what this would do, and write nothing. Needs no Idempotency-Key and spends none.
Idempotency-KeyheaderstringyesOne value per intended change, the same one on a retry. A repeat replays the first answer; a different body is a 409.

Responses: 200 Written. With dry_run: what it would do, and nothing written · 202 Filed as a proposal in the person's review inbox. Nothing is written until they accept it · 400 A parameter is missing or malformed · 401 No token, or the token is invalid, revoked or expired · 402 This write needs an active subscription · 403 About the TOKEN: it lacks the scope, or is not scoped to that budget · 404 Not reachable by this token. A nonexistent id and another owner's id answer identically · 409 See `reason` · 429 Rate limited — see Retry-After · 500 Something went wrong. The body never names internals

get/proposals

List proposals

What came of what was proposed, newest first. Needs the `propose` or `write` scope. Paged by cursor only.

ParameterInTypeRequiredNotes
budget_idquerystringyesThe budget to read. Required on every budget-scoped resource.
statusquerystringnoopen (the default), accepted, edited, dismissed, expired or superseded.
limitqueryintegerno1–500.
cursorquerystringnoA `next_cursor` from the page before.

Responses: 200 OK · 400 A parameter is missing or malformed · 401 No token, or the token is invalid, revoked or expired · 403 About the TOKEN: it lacks the scope, or is not scoped to that budget · 404 Not reachable by this token. A nonexistent id and another owner's id answer identically · 429 Rate limited — see Retry-After · 500 Something went wrong. The body never names internals

get/proposals/{id}

Get one proposal

Its payload and what it would change as of now. A person accepts or dismisses it in Rudopo; no token can.

ParameterInTypeRequiredNotes
idpathstringyes

Responses: 200 OK · 400 A parameter is missing or malformed · 401 No token, or the token is invalid, revoked or expired · 403 About the TOKEN: it lacks the scope, or is not scoped to that budget · 404 Not reachable by this token. A nonexistent id and another owner's id answer identically · 429 Rate limited — see Retry-After · 500 Something went wrong. The body never names internals

Shapes

Money fields are decimal strings in major units — parse them with a decimal type, never a float.

An account's currency is always its effective ISO 4217 code, even when it has no override of its own — see the full list at /currencies.

Budget

idstring
spaceIdstring
spaceNamestring | null
namestring
currencystringISO 4217 code, e.g. USD
createdAtstring | nullISO-8601 UTC
archivedAtstring | nullISO-8601 UTC. Set when a clean slate left this budget behind as an archive; its balances also live in the successor budget.

Account

idstring
namestring
typestringAccount type
currencystringISO 4217 code, e.g. USD — always populated, even for an account with no currency override
onBudgetboolean
closedboolean
balancestringCleared + uncleared, budget currency, AS OF TODAY (server date, UTC). Future-dated transactions are excluded here but ARE counted by transactionCount and lastTransactionDate, so summing /transactions for this account will not equal this figure whenever one exists.
clearedBalancestringDecimal string, major units, at the currency's ISO 4217 decimals, e.g. "-45.00" (USD), "1840" (JPY), "1.234" (KWD)
unclearedBalancestringDecimal string, major units, at the currency's ISO 4217 decimals, e.g. "-45.00" (USD), "1840" (JPY), "1.234" (KWD)
nativeBalancestringBalance in the account's own currency
transactionCountinteger
lastTransactionDatestring | nullYYYY-MM-DD
createdAtstring | null

Transaction

idstring
datestringYYYY-MM-DD, no timezone
accountIdstring
accountNamestring | null
payeeIdstring | null
payeeNamestring | null
categoryIdstring | null
categoryNamestring | null
memostring
amountstringNegative = outflow. Budget currency.
amountNativestring | nullSet only on foreign-currency accounts
exchangeRatenumber | null
currencystringThe account's ISO 4217 code, the budget's when the account has none of its own
typestringTransaction kind
clearedboolean
reconciledboolean
transferAccountIdstring | null
splitGroupIdstring | nullShared by every leg of a split
labelsobject[]
createdAtstring | null
versionintegerSend this back on PATCH: an edit of a row that moved since is refused
moneyobjectThe same figures as `amount`, `amountNative` and `exchangeRate`, as the objects a write and a dry run answer with

Category

idstring
groupIdstring
namestring
hiddenboolean
notestring | null
emojistring | nullThe category's picked icon, or null for the automatic one

CategoryGroup

idstring
namestring
hiddenboolean
budgetModestringWhere this group is funded
categoriesobject[]

Payee

idstring
namestring

Label

idstring
namestring

Month

monthstringYYYY-MM
readyToAssignstringDecimal string, major units, at the currency's ISO 4217 decimals, e.g. "-45.00" (USD), "1840" (JPY), "1.234" (KWD)
assignedstringAssigned in this month. Ready-to-Assign arithmetic: it includes money assigned to credit-card payment categories, unlike the in-app reports' Assigned and the Budget screen's Assigned tile.
cashBalancestringDecimal string, major units, at the currency's ISO 4217 decimals, e.g. "-45.00" (USD), "1840" (JPY), "1.234" (KWD)
overspentTotalstringDecimal string, major units, at the currency's ISO 4217 decimals, e.g. "-45.00" (USD), "1840" (JPY), "1.234" (KWD)
overspentCountinteger
uncategorizedCountinteger
heldForNextMonthstringDecimal string, major units, at the currency's ISO 4217 decimals, e.g. "-45.00" (USD), "1840" (JPY), "1.234" (KWD)

Money

amountstringDecimal string, major units, at the currency's ISO 4217 decimals, e.g. "-45.00" (USD), "1840" (JPY), "1.234" (KWD)
currencystringISO 4217 code

Proposal

idstring
kindstringThe change proposed, e.g. transaction.create
summarystringOne line, written by Rudopo from the figures
statusstring
flagsstring[]ceiling_exceeded, possible_duplicate, demoted, needs_person
actorLabelstring | nullThe token or app that proposed it
dismissReasonstring | nullWhat the person said when they dismissed it
createdAtstring | null
decidedAtstring | null
resultIdstring | nullThe row the accepted write made, when it made one
stalebooleanTrue when an open proposal can no longer be accepted: its target moved

CreateTransaction

account_idstring
datestring
amountstringNegative for money out, in the budget's currency. On a foreign account, send amount_native instead, or this with amount_is_explicit
amount_nativestring | nullIn the account's own currency. The budget amount is converted at the rate for `date`
transfer_amount_nativestring | nullWhat arrived, in the destination account's currency
amount_is_explicitboolean`amount` is the converted figure you mean: the rate stored is the one it implies
payee_idstring | null
payee_namestring | null
category_idstring | null
memostring
clearedboolean
transfer_account_idstring | nullMakes this a transfer: two rows, one value
label_idsstring[]
splitsobject[]Makes this a split. Their amounts add up to `amount`

BatchTransactions

transactionsobject[]

UpdateTransaction

versionintegerThe row's `version` as you read it
datestring
amountstring
amount_nativestring | null
payee_idstring | null
payee_namestring | null
category_idstring | null
memostring
clearedboolean
account_idstring
transfer_account_idstring | null

LinkLabel

label_idstring

CreateCategory

group_idstring
namestring

UpdateCategory

namestring
hiddenboolean
notestring | null
group_idstring
emojistring | nullOne of Rudopo's curated category icons, exactly as listed, or null for the automatic one

SetTarget

typestring
amountstring
target_datestring | null
monthly_amountstring | null
cadencestring | null
cadence_frequencyinteger | null
dayinteger | null
needs_whole_amountboolean | null
repeatboolean | null

CreatePayee

namestring

RenamePayee

namestring

Assign

assignedstring

Move

Proposed

outcomestring
reasonstringSet when a token that may write was sent to the review inbox instead
messagestring
proposalobject

DryRun

outcomestring
dry_runboolean
wouldstring
reasonstring
summarystring
flagsstring[]
diffobject

Pagination

limitinteger
offsetintegerAbsent when paging by cursor
has_morebooleanBy offset, true when the page was full. By cursor, true when next_cursor is set
next_cursorstring | nullSend as `cursor` for the next page. Null on the last

Error

errorobject

Back to Developers