API · 16 operations

Payees

Clean names for where money went, and the rules that name and file by them.

get /v1/payees

Every payee, with how many rules and transactions carry it and when it was last used

scope budget:read · listPayees

Parameters

  • budget_id query · string

Returns · 200

{ payees: [{ id, name, rule_count, transaction_count, last_used_on, spent_cents, received_cents }] }, alphabetical. transaction_count and last_used_on (the newest date on a row carrying it, null when none does) count every budget. Pass budget_id (or default) for spent_cents and received_cents: money out to the payee and money in from it in that budget, in its currency (also returned as currency), with transfers between your own accounts left out. Without budget_id both are null, because two budgets may count in different currencies.

Example

curl 'https://api.mintro.money/v1/payees' \ -H "Authorization: Bearer $MINTRO_KEY"

Errors · besides 401, 429, 500

  • 403

    forbidden: The key is valid but lacks the scope this call needs. Ask the human to mint a key with the scope named in the message.

post /v1/payees

Make a payee (or find the one with that name)

scope budget:write · createPayee

Body · JSON

  • name string · required · ≤ 120 chars

Returns · 201

{ id, name, rule_count, transaction_count, last_used_on, spent_cents: null, received_cents: null }. Names are one payee whatever their case.

Example

curl -X POST 'https://api.mintro.money/v1/payees' \ -H "Authorization: Bearer $MINTRO_KEY" \ -H 'Content-Type: application/json' \ -d '{ "name": "<name>" }'

Errors · besides 401, 429, 500

  • 400

    validation_failed: The request body or query is malformed. The message names the offending field; fix it and retry.

  • 403

    forbidden: The key is valid but lacks the scope this call needs. Ask the human to mint a key with the scope named in the message.

  • 409

    idempotency_conflict: This Idempotency-Key was used for a different request, or the first request is still in flight. Retry the in-flight case after a second; use a fresh key for a genuinely different request.

get /v1/payees/unnamed

Names on transactions that have no payee yet

scope budget:read · listUnnamedPayees

Returns · 200

{ names: [{ name, transaction_count }] }: every distinct name on a row with no payee, whoever wrote it (the person, an import, an agent, the bank), most used first. Transfers, income and opening rows are left out. Reads only.

Example

curl 'https://api.mintro.money/v1/payees/unnamed' \ -H "Authorization: Bearer $MINTRO_KEY"

Errors · besides 401, 429, 500

  • 403

    forbidden: The key is valid but lacks the scope this call needs. Ask the human to mint a key with the scope named in the message.

post /v1/payees/adopt

Keep names as payees

scope budget:write · adoptPayees

Body · JSON

  • names string[] · ≤ 5000 items

  • rename object

Returns · 200

{ payees_made, transactions_named }. Each name becomes a payee and its rows with no payee take it; the words on the row stay. Omit names to keep them all; rename: { "TIM HORTONS #123": "Tim Hortons" } keeps a name as a different payee (joining it if it exists). Rows that already have a payee are untouched.

Example

curl -X POST 'https://api.mintro.money/v1/payees/adopt' \ -H "Authorization: Bearer $MINTRO_KEY" \ -H 'Content-Type: application/json' \ -d '{ "names": [ "<names>" ], "rename": {} }'

Errors · besides 401, 429, 500

  • 400

    validation_failed: The request body or query is malformed. The message names the offending field; fix it and retry.

  • 403

    forbidden: The key is valid but lacks the scope this call needs. Ask the human to mint a key with the scope named in the message.

  • 409

    idempotency_conflict: This Idempotency-Key was used for a different request, or the first request is still in flight. Retry the in-flight case after a second; use a fresh key for a genuinely different request.

patch /v1/payees/{id}

Rename a payee everywhere; onto an existing name, merge into it

scope budget:write · renamePayee

Parameters

  • id path · string · required

Body · JSON

  • name string · required · ≤ 120 chars

Returns · 200

{ id, name, merged_into }. Every transaction and rule with this payee shows the new name.

Example

curl -X PATCH 'https://api.mintro.money/v1/payees/<id>' \ -H "Authorization: Bearer $MINTRO_KEY" \ -H 'Content-Type: application/json' \ -d '{ "name": "<name>" }'

Errors · besides 401, 429, 500

  • 400

    validation_failed: The request body or query is malformed. The message names the offending field; fix it and retry.

  • 403

    forbidden: The key is valid but lacks the scope this call needs. Ask the human to mint a key with the scope named in the message.

  • 404

    not_found: No such record on this budget. Re-read GET /v1/budgets/{id} (or the relevant list) for current ids rather than reusing a remembered one.

  • 409

    idempotency_conflict: This Idempotency-Key was used for a different request, or the first request is still in flight. Retry the in-flight case after a second; use a fresh key for a genuinely different request.

delete /v1/payees/{id}

Delete a payee and its rules; its transactions keep the bank's words

scope budget:write · deletePayee

Parameters

  • id path · string · required

Returns · 200

{ deleted: true }.

Example

curl -X DELETE 'https://api.mintro.money/v1/payees/<id>' \ -H "Authorization: Bearer $MINTRO_KEY"

Errors · besides 401, 429, 500

  • 403

    forbidden: The key is valid but lacks the scope this call needs. Ask the human to mint a key with the scope named in the message.

  • 404

    not_found: No such record on this budget. Re-read GET /v1/budgets/{id} (or the relevant list) for current ids rather than reusing a remembered one.

  • 409

    idempotency_conflict: This Idempotency-Key was used for a different request, or the first request is still in flight. Retry the in-flight case after a second; use a fresh key for a genuinely different request.

post /v1/payees/{id}/merge

Merge this payee into another

scope budget:write · mergePayees

Parameters

  • id path · string · required

Body · JSON

  • into_payee_id string · required · ≤ 64 chars

Returns · 200

{ moved_transactions, moved_rules }. This payee goes; the other keeps everything.

Example

curl -X POST 'https://api.mintro.money/v1/payees/<id>/merge' \ -H "Authorization: Bearer $MINTRO_KEY" \ -H 'Content-Type: application/json' \ -d '{ "into_payee_id": "<into_payee_id>" }'

Errors · besides 401, 429, 500

  • 400

    validation_failed: The request body or query is malformed. The message names the offending field; fix it and retry.

  • 403

    forbidden: The key is valid but lacks the scope this call needs. Ask the human to mint a key with the scope named in the message.

  • 404

    not_found: No such record on this budget. Re-read GET /v1/budgets/{id} (or the relevant list) for current ids rather than reusing a remembered one.

  • 409

    idempotency_conflict: This Idempotency-Key was used for a different request, or the first request is still in flight. Retry the in-flight case after a second; use a fresh key for a genuinely different request.

get /v1/payee-rules

Every payee rule, in the order they are tried

scope budget:read · listPayeeRules

Returns · 200

{ rules: [{ id, payee_id, payee, match, pattern, field, account_id, amount_min_cents, amount_max_cents, direction, budget_id, envelope_id, envelope, auto_file, position }] }. The first rule whose conditions all hold names the row.

Example

curl 'https://api.mintro.money/v1/payee-rules' \ -H "Authorization: Bearer $MINTRO_KEY"

Errors · besides 401, 429, 500

  • 403

    forbidden: The key is valid but lacks the scope this call needs. Ask the human to mint a key with the scope named in the message.

post /v1/payee-rules

Add a payee rule, only after the human agreed and after previewing it

scope budget:write · createPayeeRule

Body · JSON

  • payee_id string · ≤ 64 chars

  • payee string · ≤ 120 chars

  • match "contains" | "starts_with" | "ends_with" | "exact" | "wildcard" · required

  • pattern string · required · ≤ 200 chars

  • field "description" | "merchant"

  • account_id string | null · ≤ 64 chars

  • amount_min_cents integer | null · ≥ 0 · ≤ 100000000000

  • amount_max_cents integer | null · ≥ 0 · ≤ 100000000000

  • direction "any" | "out" | "in"

  • budget_id string | null · ≤ 64 chars

  • envelope_id string | null · ≤ 64 chars

  • auto_file boolean

  • position integer · ≥ 0

Returns · 201

{ id, payee_id, payee, match, pattern, field, account_id, amount_min_cents, amount_max_cents, direction, budget_id, envelope_id, envelope, auto_file, position }. match is contains | starts_with | ends_with | exact | wildcard (* for any run); matching ignores case and runs of spaces. field: description reads the bank's name and merchant, merchant the merchant alone. account_id, amount_min_cents/amount_max_cents (magnitudes) and direction (out | in | any) narrow it. envelope_id (in budget_id) with auto_file: true files a matching row that is still unfiled when it lands; a filed row is never moved. New rules go last unless position says otherwise.

Example

curl -X POST 'https://api.mintro.money/v1/payee-rules' \ -H "Authorization: Bearer $MINTRO_KEY" \ -H 'Content-Type: application/json' \ -d '{ "match": "contains", "pattern": "<pattern>" }'

Errors · besides 401, 429, 500

  • 400

    validation_failed: The request body or query is malformed. The message names the offending field; fix it and retry.

  • 403

    forbidden: The key is valid but lacks the scope this call needs. Ask the human to mint a key with the scope named in the message.

  • 404

    not_found: No such record on this budget. Re-read GET /v1/budgets/{id} (or the relevant list) for current ids rather than reusing a remembered one.

  • 409

    idempotency_conflict: This Idempotency-Key was used for a different request, or the first request is still in flight. Retry the in-flight case after a second; use a fresh key for a genuinely different request.

post /v1/payee-rules/preview

Test a rule before saving it: what it would name and file. Writes nothing

scope budget:read · previewPayeeRules

Body · JSON

  • rule object

  • rule.payee_id string · ≤ 64 chars

  • rule.payee string · ≤ 120 chars

  • rule.match "contains" | "starts_with" | "ends_with" | "exact" | "wildcard" · required

  • rule.pattern string · required · ≤ 200 chars

  • rule.field "description" | "merchant"

  • rule.account_id string | null · ≤ 64 chars

  • rule.amount_min_cents integer | null · ≥ 0 · ≤ 100000000000

  • rule.amount_max_cents integer | null · ≥ 0 · ≤ 100000000000

  • rule.direction "any" | "out" | "in"

  • rule.budget_id string | null · ≤ 64 chars

  • rule.envelope_id string | null · ≤ 64 chars

  • rule.auto_file boolean

  • rule.id string · ≤ 64 chars

Returns · 200

{ transactions, staged, would_name, would_rename, would_file, claimed_elsewhere, sample: [{ kind: transaction|staged, id, date, amount_cents, text, merchant, current_payee, new_payee, envelope, already_filed, claimed_by }] }. With rule, the draft is tested alone (placed last, or in its own place when rule.id names a saved rule) across the most recent 5000 transactions and everything waiting in bank staging; claimed_by names an earlier rule that takes a row first. Without rule, it shows what every saved rule does. Show the human the sample before saving.

Example

curl -X POST 'https://api.mintro.money/v1/payee-rules/preview' \ -H "Authorization: Bearer $MINTRO_KEY" \ -H 'Content-Type: application/json' \ -d '{ "rule": { "match": "contains", "pattern": "<pattern>" } }'

Errors · besides 401, 429, 500

  • 400

    validation_failed: The request body or query is malformed. The message names the offending field; fix it and retry.

  • 403

    forbidden: The key is valid but lacks the scope this call needs. Ask the human to mint a key with the scope named in the message.

  • 404

    not_found: No such record on this budget. Re-read GET /v1/budgets/{id} (or the relevant list) for current ids rather than reusing a remembered one.

  • 409

    idempotency_conflict: This Idempotency-Key was used for a different request, or the first request is still in flight. Retry the in-flight case after a second; use a fresh key for a genuinely different request.

post /v1/payee-rules/suggest

A first-guess rule from bank text: the words without store numbers or how-it-moved words

scope budget:read · suggestPayeeRule

Body · JSON

  • text string · required · ≤ 300 chars

Returns · 200

{ match, pattern }, e.g. TIM HORTONS #1234 CALGARY → contains tim hortons (the clean run up to the first number, since contains is literal). Preview it before saving.

Example

curl -X POST 'https://api.mintro.money/v1/payee-rules/suggest' \ -H "Authorization: Bearer $MINTRO_KEY" \ -H 'Content-Type: application/json' \ -d '{ "text": "<text>" }'

Errors · besides 401, 429, 500

  • 400

    validation_failed: The request body or query is malformed. The message names the offending field; fix it and retry.

  • 403

    forbidden: The key is valid but lacks the scope this call needs. Ask the human to mint a key with the scope named in the message.

  • 409

    idempotency_conflict: This Idempotency-Key was used for a different request, or the first request is still in flight. Retry the in-flight case after a second; use a fresh key for a genuinely different request.

put /v1/payee-rules/order

Set the order rules are tried in; the first match wins

scope budget:write · reorderPayeeRules

Body · JSON

  • rule_ids string[] · required · ≤ 1000 items

Returns · 200

{ rules: [{ id, payee_id, payee, match, pattern, field, account_id, amount_min_cents, amount_max_cents, direction, budget_id, envelope_id, envelope, auto_file, position }] } in the new order. Rules not named keep their place after the named ones.

Example

curl -X PUT 'https://api.mintro.money/v1/payee-rules/order' \ -H "Authorization: Bearer $MINTRO_KEY" \ -H 'Content-Type: application/json' \ -d '{ "rule_ids": [ "<rule_ids>" ] }'

Errors · besides 401, 429, 500

  • 400

    validation_failed: The request body or query is malformed. The message names the offending field; fix it and retry.

  • 403

    forbidden: The key is valid but lacks the scope this call needs. Ask the human to mint a key with the scope named in the message.

  • 404

    not_found: No such record on this budget. Re-read GET /v1/budgets/{id} (or the relevant list) for current ids rather than reusing a remembered one.

  • 409

    idempotency_conflict: This Idempotency-Key was used for a different request, or the first request is still in flight. Retry the in-flight case after a second; use a fresh key for a genuinely different request.

get /v1/payee-rules/{id}

One payee rule

scope budget:read · getPayeeRule

Parameters

  • id path · string · required

Returns · 200

{ id, payee_id, payee, match, pattern, field, account_id, amount_min_cents, amount_max_cents, direction, budget_id, envelope_id, envelope, auto_file, position }

Example

curl 'https://api.mintro.money/v1/payee-rules/<id>' \ -H "Authorization: Bearer $MINTRO_KEY"

Errors · besides 401, 429, 500

  • 403

    forbidden: The key is valid but lacks the scope this call needs. Ask the human to mint a key with the scope named in the message.

  • 404

    not_found: No such record on this budget. Re-read GET /v1/budgets/{id} (or the relevant list) for current ids rather than reusing a remembered one.

patch /v1/payee-rules/{id}

Change a payee rule

scope budget:write · updatePayeeRule

Parameters

  • id path · string · required

Body · JSON

  • payee_id string · ≤ 64 chars

  • payee string · ≤ 120 chars

  • match "contains" | "starts_with" | "ends_with" | "exact" | "wildcard"

  • pattern string · ≤ 200 chars

  • field "description" | "merchant"

  • account_id string | null · ≤ 64 chars

  • amount_min_cents integer | null · ≥ 0 · ≤ 100000000000

  • amount_max_cents integer | null · ≥ 0 · ≤ 100000000000

  • direction "any" | "out" | "in"

  • budget_id string | null · ≤ 64 chars

  • envelope_id string | null · ≤ 64 chars

  • auto_file boolean

Returns · 200

{ id, payee_id, payee, match, pattern, field, account_id, amount_min_cents, amount_max_cents, direction, budget_id, envelope_id, envelope, auto_file, position } after the change. Rows already named keep their name until POST .../apply.

Example

curl -X PATCH 'https://api.mintro.money/v1/payee-rules/<id>' \ -H "Authorization: Bearer $MINTRO_KEY" \ -H 'Content-Type: application/json' \ -d '{ "payee_id": "<payee_id>", "payee": "<payee>" }'

Errors · besides 401, 429, 500

  • 400

    validation_failed: The request body or query is malformed. The message names the offending field; fix it and retry.

  • 403

    forbidden: The key is valid but lacks the scope this call needs. Ask the human to mint a key with the scope named in the message.

  • 404

    not_found: No such record on this budget. Re-read GET /v1/budgets/{id} (or the relevant list) for current ids rather than reusing a remembered one.

  • 409

    idempotency_conflict: This Idempotency-Key was used for a different request, or the first request is still in flight. Retry the in-flight case after a second; use a fresh key for a genuinely different request.

delete /v1/payee-rules/{id}

Delete a payee rule; rows it named keep their payee

scope budget:write · deletePayeeRule

Parameters

  • id path · string · required

Returns · 200

{ deleted: true }.

Example

curl -X DELETE 'https://api.mintro.money/v1/payee-rules/<id>' \ -H "Authorization: Bearer $MINTRO_KEY"

Errors · besides 401, 429, 500

  • 403

    forbidden: The key is valid but lacks the scope this call needs. Ask the human to mint a key with the scope named in the message.

  • 404

    not_found: No such record on this budget. Re-read GET /v1/budgets/{id} (or the relevant list) for current ids rather than reusing a remembered one.

  • 409

    idempotency_conflict: This Idempotency-Key was used for a different request, or the first request is still in flight. Retry the in-flight case after a second; use a fresh key for a genuinely different request.

post /v1/payee-rules/{id}/apply

Apply one rule to transactions already in the budget

scope budget:write · applyPayeeRule

Parameters

  • id path · string · required

Body · JSON

  • overwrite boolean

  • file_unfiled boolean

Returns · 200

{ named, renamed, filed }. Names the rows this rule decides that have no payee; overwrite: true renames every row it decides; file_unfiled: true files the unfiled ones into the rule's envelope. A filed row is never moved; a row an earlier rule decides is left to it. Preview first.

Example

curl -X POST 'https://api.mintro.money/v1/payee-rules/<id>/apply' \ -H "Authorization: Bearer $MINTRO_KEY" \ -H 'Content-Type: application/json' \ -d '{ "overwrite": true, "file_unfiled": true }'

Errors · besides 401, 429, 500

  • 400

    validation_failed: The request body or query is malformed. The message names the offending field; fix it and retry.

  • 403

    forbidden: The key is valid but lacks the scope this call needs. Ask the human to mint a key with the scope named in the message.

  • 404

    not_found: No such record on this budget. Re-read GET /v1/budgets/{id} (or the relevant list) for current ids rather than reusing a remembered one.

  • 409

    idempotency_conflict: This Idempotency-Key was used for a different request, or the first request is still in flight. Retry the in-flight case after a second; use a fresh key for a genuinely different request.