AndroMoney icon

AndroMoney cloud ledger API for shared books

KPMoney · Banking

AndroMoney is KPMoney's personal expense ledger (package com.kpmoney.android; paid sibling com.andromoney.pro). Households log income, expenses and account-to-account transfers across cash, EasyCard (悠遊卡) and bank payments, attach receipt photos, schedule periodic salary and rent rows, convert foreign amounts against a main currency, and share a book or a single record with family via a link that opens in the app or on the AndroMoney website. Taiwan users can sign into the Ministry of Finance e-invoice portal, scan invoice QR codes, check winning invoices, run an income-tax estimate and a loan calculator, then drop matching receipts onto the ledger. Cloud sync plus Google Drive and Dropbox (folder Apps/_AndroMoney_) keep the on-device SQLite book on other phones; Plus and Pro sell as andromoney.plus.monthly / yearly and andromoney.pro.monthly / yearly on Google Play Billing. It sits with other money-manager apps for people who want one household book—including Taiwan e-invoice ingest—rather than a bank's own app.

Signed ledger amounts sit in mount next to the main-currency amount_to_main, with hash_key identity, sub_category, receipt_num, and the payment hashes in_payment / out_payment. Cloud pages ship table objects whose delete and update arrays refill record_table, payment_table (payment_name, card_number, bill_date, pay_date), carrier_table keyed by card_no, and receipt images under record_hash_key. Shared books expose url_id, entity_hash_key, entity_type (Record or Project), secrecy, permission and expired_at; comments hang off entity_hash_key with content and user_email. Entitlements report plan, record_limit, image_limit, update_limit and usage.record against free/plus/pro all_limits. Taiwan carrier invoices return invNum, sellerBan, sellerName, header amount and line details (description, quantity, unitPrice); currency-pair lookups such as TWD_USD return a rate string.

Family-office jobs can rebuild P&L from mount and amount_to_main; household bots can watch shared-link url_id and comment threads; quota monitors can compare usage.record to record_limit; tax ingest can turn invNum and sellerBan into ledger rows. openData Studio turns that surface into callable open data.

Screenshots

  • AndroMoney screenshot 1
  • AndroMoney screenshot 2
  • AndroMoney screenshot 3
  • AndroMoney screenshot 4
  • AndroMoney screenshot 5

API surface

The endpoints and request/response examples below are reconstructed from the app's interface — illustrative, not a live capture.

  • Start cloud sync

    POST /v1/ledger-sync/sessions/open openfinance

    Opens a cloud-sync session for the household ledger. The client then pages the cloud book down, posts its local changes up, and closes the session. The response confirms with a message and a sync_start_time stamp.

    Auth: Device-bound session sent as JSON body fields user, device and token (no Authorization header). Accept: application/json. device_id may be null; mobile_type defaults to 0.

    • user
    • device
    • token
    • now_utc
    • device_id
    • device_type
    • mobile_type
    • message
    • sync_start_time
    POST /v1/ledger-sync/sessions/open HTTP/1.1
    Accept: application/json
    Content-Type: application/json
    
    {
      "body": {
        "user": "[email protected]",
        "device": "a1b2c3d4e5f6",
        "token": "YOUR_SYNC_TOKEN",
        "now_utc": "2026-10-21 08:15:00",
        "device_id": null,
        "device_type": "Pixel 8",
        "mobile_type": "0"
      }
    }
    {
      "message": "ok",
      "sync_start_time": "2026-10-21 08:15:01"
    }
  • Download ledger pages

    GET /v1/ledger-sync/pages openfinance

    Pages the cloud book after a session opens. The response carries total_pages plus per-table objects: single-page tables (including carrier_table keyed by card_no) are applied first, then the multi-page record_table and image_table, whose delete and update arrays upsert the on-device ledger. The signed amount's wire name is mount.

    Auth: Device-bound session as query params user, device and token (no Authorization header). Also sends device_type, page, the last-sync timestamp for the ledger table as sync_time, and now_utc. Accept: application/json.

    • total_pages
    • record_table
    • image_table
    • payment_table
    • carrier_table
    • delete
    • update
    • hash_key
    • mount
    • amount_to_main
    • currency_code
    • date
    • category
    • sub_category
    • in_payment
    • out_payment
    • receipt_num
    • payment_name
    • card_no
    • card_type
    • card_encrypt
    • payment_hash_key
    • record_hash_key
    • url
    GET /v1/ledger-sync/pages?user=ada%40example.com&device=a1b2c3d4e5f6&device_type=Pixel%208&token=YOUR_SYNC_TOKEN&page=1&sync_time=2026-10-01%2000:00:00&now_utc=2026-10-21%2008:15:00 HTTP/1.1
    Accept: application/json
    {
      "total_pages": 2,
      "record_table": {
        "delete": [
          {"hash_key": "rec_del_01"}
        ],
        "update": [
          {
            "hash_key": "rec_a1",
            "mount": "-320.00",
            "amount_to_main": "-320.00",
            "currency_code": "TWD",
            "date": "2026-10-20 12:30:00",
            "category": "cat_food",
            "sub_category": "sub_lunch",
            "in_payment": null,
            "out_payment": "pay_cash",
            "in_amount": null,
            "out_amount": "320.00",
            "in_currency": null,
            "out_currency": "TWD",
            "payee": "payee_cafe",
            "project": null,
            "period": null,
            "fee": "0",
            "remark": "Lunch",
            "receipt_num": "AB12345678",
            "status": "20",
            "update_time": "2026-10-20 12:31:00"
          }
        ]
      },
      "image_table": {
        "delete": [],
        "update": [
          {
            "hash_key": "img_01",
            "record_hash_key": "rec_a1",
            "url": "https://images.example.com/rec_a1/img_01.jpg"
          }
        ]
      },
      "payment_table": {
        "delete": [],
        "update": [
          {
            "hash_key": "pay_cash",
            "payment_name": "Cash",
            "currency_code": "TWD",
            "kind": 0,
            "card_number": null,
            "bill_date": null,
            "pay_date": null,
            "total": "12000.00"
          }
        ]
      },
      "carrier_table": {
        "delete": [],
        "update": [
          {
            "card_no": "/ABC+123",
            "card_type": "3J0002",
            "card_name": "Phone barcode",
            "card_encrypt": "****",
            "payment_hash_key": "pay_cash",
            "auto_sync": 1
          }
        ]
      }
    }
  • Upload ledger mutations

    POST /v1/ledger-sync/changes openfinance

    Pushes local inserts, updates and deletes. body.record_table holds ledger-row changes (mount, amount_to_main, sub_category) and body.images holds receipt-photo inserts and deletes. The response is a plain message.

    Auth: Device-bound session sent as JSON body.body fields user, device and token (no Authorization header). Top-level device_id repeats the device uuid. Accept: application/json.

    • device_id
    • body
    • other_count
    • record_table
    • images
    • count
    • insert
    • update
    • delete
    • hash_key
    • mount
    • amount_to_main
    • sub_category
    • receipt_num
    • payment_user_email
    • record_hash_key
    • url
    • order_no
    • message
    POST /v1/ledger-sync/changes HTTP/1.1
    Accept: application/json
    Content-Type: application/json
    
    {
      "device_id": "a1b2c3d4e5f6",
      "body": {
        "user": "[email protected]",
        "device": "a1b2c3d4e5f6",
        "token": "YOUR_SYNC_TOKEN",
        "now_utc": "2026-10-21 08:16:00",
        "device_id": "a1b2c3d4e5f6",
        "device_type": "Pixel 8",
        "mobile_type": "0",
        "other_count": 1,
        "record_table": {
          "count": 2,
          "insert": [
            {
              "hash_key": "rec_new_01",
              "mount": "-88.00",
              "amount_to_main": "-88.00",
              "currency_code": "TWD",
              "date": "2026-10-21 08:10:00",
              "category": "cat_food",
              "sub_category": "sub_coffee",
              "in_payment": null,
              "out_payment": "pay_cash",
              "in_amount": null,
              "out_amount": "88.00",
              "in_currency": null,
              "out_currency": "TWD",
              "payee": "payee_cafe",
              "project": null,
              "period": null,
              "fee": "0",
              "remark": "Coffee",
              "receipt_num": "",
              "status": "20",
              "payment_user_email": "[email protected]",
              "update_time": "2026-10-21 08:16:00"
            }
          ],
          "update": [],
          "delete": [
            {
              "hash_key": "rec_del_01",
              "in_payment": null,
              "out_payment": "pay_cash",
              "payment_user_email": "[email protected]",
              "update_time": "2026-10-21 08:16:00"
            }
          ]
        },
        "images": {
          "count": 1,
          "insert": [
            {
              "hash_key": "img_02",
              "record_hash_key": "rec_new_01",
              "url": "https://images.example.com/rec_new_01/img_02.jpg",
              "order_no": "1",
              "payment_user_email": "[email protected]",
              "update_time": "2026-10-21 08:16:00"
            }
          ],
          "delete": []
        }
      }
    }
    {
      "message": "ok"
    }
  • End cloud sync

    POST /v1/ledger-sync/sessions/close openfinance

    Closes the sync session opened earlier. The request adds a sync_time stamp, which the client stores as the last-sync marker for the ledger table so the next pass only fetches newer changes.

    Auth: Device-bound session sent as JSON body.body fields user, device and token (no Authorization header). Accept: application/json.

    • user
    • device
    • token
    • now_utc
    • device_id
    • device_type
    • sync_time
    • message
    POST /v1/ledger-sync/sessions/close HTTP/1.1
    Accept: application/json
    Content-Type: application/json
    
    {
      "body": {
        "user": "[email protected]",
        "device": "a1b2c3d4e5f6",
        "token": "YOUR_SYNC_TOKEN",
        "now_utc": "2026-10-21 08:17:00",
        "device_id": null,
        "device_type": "Pixel 8",
        "mobile_type": "0",
        "sync_time": "2026-10-21 08:17:00"
      }
    }
    {
      "message": "ok"
    }
  • Load shared records

    GET /v1/shared-books/{linkId}/entries openfinance

    Loads one page of a shared book. The response returns share_link (url_id, entity_type Record or Project, secrecy, permission) plus nested records with record.mount and amount_to_main, joined to category, subcategory, payments, currency, comments and images. user_email marks which rows belong to the signed-in user.

    Auth: Device-bound session as query params user, device and token (no Authorization header). The client requests 30 rows per page via per_page. Accept: application/json.

    • message
    • share_link
    • url_id
    • entity_type
    • entity_hash_key
    • permission
    • secrecy
    • expired_at
    • title
    • records
    • user_email
    • mount
    • amount_to_main
    • hash_key
    • sub_category
    • receipt_num
    • payment_name
    • subcategory
    • id_category
    GET /v1/shared-books/abcUrlId01/entries?device=a1b2c3d4e5f6&user=ada%40example.com&token=YOUR_SYNC_TOKEN&per_page=30&page=1 HTTP/1.1
    Accept: application/json
    {
      "message": null,
      "share_link": {
        "id": 4412,
        "url_id": "abcUrlId01",
        "title": "October household",
        "entity_type": "Record",
        "entity_hash_key": "rec_a1",
        "entity_user_id": 1001,
        "user_id": 1001,
        "permission": 1,
        "secrecy": 0,
        "expired_at": "2026-12-31 23:59:59",
        "created_at": "2026-10-01 09:00:00",
        "updated_at": "2026-10-20 12:00:00"
      },
      "records": [
        {
          "user_email": "[email protected]",
          "record": {
            "id": 88,
            "hash_key": "rec_a1",
            "mount": "-320.00",
            "amount_to_main": "-320.00",
            "currency_code": "TWD",
            "date": "2026-10-20 12:30:00",
            "category": "cat_food",
            "sub_category": "sub_lunch",
            "in_payment": null,
            "out_payment": "pay_cash",
            "in_amount": null,
            "out_amount": "320.00",
            "receipt_num": "AB12345678",
            "remark": "Lunch",
            "status": 20,
            "is_delete": false
          },
          "category": {
            "hash_key": "cat_food",
            "category": "Food",
            "type": 20
          },
          "subcategory": {
            "hash_key": "sub_lunch",
            "subcategory": "Lunch",
            "id_category": "cat_food"
          },
          "out_payment": {
            "hash_key": "pay_cash",
            "payment_name": "Cash",
            "currency_code": "TWD",
            "kind": 0,
            "total": "12000.00"
          },
          "currency": {
            "currency_code": "TWD",
            "rate": "1"
          },
          "comment": [],
          "image": []
        }
      ]
    }
  • List share links

    GET /v1/shared-books/links opendata

    Lists links the user owns (share_links) and links shared to them (links_share_to_me). The client queries entity_type Record and Project and merges both into one share-links screen. Opening a shared link launches the book inside the app.

    Auth: Device-bound session as query params user, device and token (no Authorization header). entity_type is Record or Project; the client merges both lists. Accept: application/json.

    • share_links
    • links_share_to_me
    • id
    • url_id
    • title
    • entity_type
    • entity_hash_key
    • entity_user_id
    • user_id
    • permission
    • secrecy
    • expired_at
    • created_at
    • updated_at
    GET /v1/shared-books/links?device=a1b2c3d4e5f6&user=ada%40example.com&token=YOUR_SYNC_TOKEN&entity_type=Record HTTP/1.1
    Accept: application/json
    {
      "share_links": [
        {
          "id": 4412,
          "url_id": "abcUrlId01",
          "title": "October household",
          "entity_type": "Record",
          "entity_hash_key": "rec_a1",
          "entity_user_id": 1001,
          "user_id": 1001,
          "permission": 1,
          "secrecy": 0,
          "expired_at": "2026-12-31 23:59:59",
          "created_at": "2026-10-01 09:00:00",
          "updated_at": "2026-10-20 12:00:00"
        }
      ],
      "links_share_to_me": [
        {
          "id": 5520,
          "url_id": "xyzUrlId99",
          "title": "Trip Kyoto",
          "entity_type": "Project",
          "entity_hash_key": "proj_kyoto",
          "permission": 0,
          "secrecy": 1,
          "expired_at": null
        }
      ]
    }
  • Create share link

    POST /v1/shared-books/publish opendata

    Creates a share link for the given record hash_keys and returns its url_id. The client then sets a title on the new link. Sharing variants cover a record set, a project, or a single record.

    Auth: Device-bound session sent as JSON body.body fields user, device and token (no Authorization header). Accept: application/json.

    • user
    • device
    • token
    • hash_keys
    • msg
    • success
    • url_id
    POST /v1/shared-books/publish HTTP/1.1
    Accept: application/json
    Content-Type: application/json
    
    {
      "body": {
        "user": "[email protected]",
        "device": "a1b2c3d4e5f6",
        "token": "YOUR_SYNC_TOKEN"
      },
      "hash_keys": ["rec_a1", "rec_b2"]
    }
    {
      "msg": null,
      "success": true,
      "url_id": "abcUrlId01"
    }
  • List users who share a payment

    GET /v1/accounts/collaborators opendata

    Lists collaborators the owner has shared a payment account with. Each entry carries email, a numeric id, is_approved and permission; payment_hash_key picks the account.

    Auth: Device-bound token as query param token plus owner_user (no Authorization header). Accept: application/json.

    • owner_user
    • payment_hash_key
    • token
    • email
    • id
    • is_approved
    • permission
    GET /v1/accounts/collaborators?owner_user=ada%40example.com&payment_hash_key=pay_cash&token=YOUR_SYNC_TOKEN HTTP/1.1
    Accept: application/json
    [
      {
        "email": "[email protected]",
        "id": 2002,
        "is_approved": true,
        "permission": 1
      }
    ]
  • List record comments

    GET /v1/entry-notes opendata

    Pages comments on shared payment records. The response wraps data plus success and total_pages; each comment carries entity_hash_key, entity_type Record and user_email. The client walks pages of 10 until the last one.

    Auth: Device-bound session as query params user, device and token (no Authorization header). The client pages 10 rows at a time until total_pages.

    • success
    • total_pages
    • data
    • id
    • hash_key
    • content
    • entity_hash_key
    • entity_type
    • entity_user_id
    • root_entity_hash_key
    • root_entity_type
    • replies_count
    • is_delete
    • user_email
    • user_name
    • created_at
    • updated_at
    GET /v1/entry-notes?user=ada%40example.com&device=a1b2c3d4e5f6&token=YOUR_SYNC_TOKEN&start_date=2026-10-01&end_date=2026-10-22&page=1&per_page=10&payment_user_email=ada%40example.com&payment_hash_key=pay_cash HTTP/1.1
    {
      "success": true,
      "total_pages": 1,
      "data": [
        {
          "id": 91,
          "hash_key": "cmt_01",
          "content": "Split this with Bob",
          "entity_hash_key": "rec_a1",
          "entity_type": "Record",
          "entity_user_id": "1001",
          "root_entity_hash_key": "rec_a1",
          "root_entity_type": "Record",
          "root_entity_user_id": "1001",
          "replies_count": 0,
          "is_delete": false,
          "user_email": "[email protected]",
          "user_name": "Ada",
          "user_id": 1001,
          "created_at": "2026-10-20 13:00:00",
          "updated_at": "2026-10-20 13:00:00",
          "update_time": "2026-10-20 13:00:00"
        }
      ]
    }
  • Post a record comment

    POST /v1/entry-notes/add opendata

    Posts a comment on a Record. The entity type is fixed to Record and the comment text travels in value; the result reuses the comment-list envelope.

    Auth: Device-bound session sent as JSON body fields user, device and token (no Authorization header).

    • user
    • device
    • token
    • entity_hash_key
    • entity_type
    • entity_user_email
    • value
    • success
    • data
    • hash_key
    • content
    • user_email
    • user_name
    POST /v1/entry-notes/add HTTP/1.1
    Content-Type: application/json
    
    {
      "user": "[email protected]",
      "device": "a1b2c3d4e5f6",
      "token": "YOUR_SYNC_TOKEN",
      "entity_hash_key": "rec_a1",
      "entity_type": "Record",
      "entity_user_email": "[email protected]",
      "value": "Split this with Bob"
    }
    {
      "success": true,
      "total_pages": 1,
      "data": {
        "id": 91,
        "hash_key": "cmt_01",
        "content": "Split this with Bob",
        "entity_hash_key": "rec_a1",
        "entity_type": "Record",
        "user_email": "[email protected]",
        "user_name": "Ada"
      }
    }
  • Get subscription entitlements

    GET /v1/plan/entitlements opendata

    Reads Plus/Pro entitlements after a Play Billing purchase. The response stores plan, expires_at, per-resource limits and usage; all_limits lists the free, plus and pro tiers. A companion purchase-report call submits the platform, product id, package name and purchase token.

    Auth: Device-bound session as query params user, device and token (no Authorization header). Accept: application/json.

    • plan
    • platform
    • expires_at
    • message
    • record_limit
    • image_limit
    • update_limit
    • usage
    • usage.record
    • usage.image
    • usage.update
    • all_limits
    • all_limits.free
    • all_limits.plus
    • all_limits.pro
    GET /v1/plan/entitlements?user=ada%40example.com&device=a1b2c3d4e5f6&token=YOUR_SYNC_TOKEN HTTP/1.1
    Accept: application/json
    {
      "plan": "plus",
      "platform": "android",
      "expires_at": "2027-10-21T08:00:00Z",
      "message": null,
      "record_limit": 20000,
      "image_limit": 5000,
      "update_limit": 20000,
      "usage": {
        "record": 4120,
        "image": 88,
        "update": 3900
      },
      "all_limits": {
        "free": {"record": 500, "image": 50, "update": 500},
        "plus": {"record": 20000, "image": 5000, "update": 20000},
        "pro": {"record": 100000, "image": 20000, "update": 100000}
      }
    }
  • Carrier invoice detail

    POST /v1/invoices/carrier/detail openfinance

    Fetches one Taiwan carrier e-invoice. The app maps invNum, sellerBan and amount onto a ledger row (receipt_num, mount). A sister lookup covers barcode and QR scans; donateMark 1 means the invoice was donated.

    Auth: Taiwan MOF e-invoice appID plus carrier cardNo, cardEncrypt and cardType. Also uuid, timeStamp and expTimeStamp. Sent as a form body, not the AndroMoney user/device/token.

    • appID
    • cardEncrypt
    • cardNo
    • cardType
    • invDate
    • invNum
    • code
    • msg
    • v
    • invPeriod
    • invStatus
    • invoiceTime
    • amount
    • sellerBan
    • sellerName
    • sellerAddress
    • details
    • description
    • quantity
    • unitPrice
    • rowNum
    POST /v1/invoices/carrier/detail HTTP/1.1
    Content-Type: application/x-www-form-urlencoded
    
    appID=<mof-app-id>&cardEncrypt=****&cardNo=%2FABC%2B123&cardType=3J0002&invDate=2026%2F10%2F20&expTimeStamp=2147483647&timeStamp=1761034500&uuid=device-uuid-01&invNum=AB12345678
    {
      "code": "200",
      "msg": "執行成功",
      "v": "0.5",
      "invNum": "AB12345678",
      "invDate": "2026/10/20",
      "invPeriod": "11510",
      "invStatus": "2",
      "invoiceTime": "12:30:00",
      "amount": "320",
      "sellerBan": "12345678",
      "sellerName": "Cafe Example",
      "sellerAddress": "Taipei",
      "details": [
        {
          "rowNum": "1",
          "description": "Latte",
          "quantity": "1",
          "unitPrice": "120",
          "amount": "120"
        },
        {
          "rowNum": "2",
          "description": "Sandwich",
          "quantity": "1",
          "unitPrice": "200",
          "amount": "200"
        }
      ]
    }
  • Convert currency pair

    GET /v1/rates/pair opendata

    Looks up a rate for a {from}_{to} currency pair. The reply is an object whose key equals the requested pair and whose value is the rate string; the app stores it and recomputes amount_to_main when the main currency changes.

    Auth: Provider apiKey as a query param (substitute your own). Separate from the AndroMoney user/device/token session. compact=ultra.

    • q
    • compact
    • apiKey
    GET /v1/rates/pair?compact=ultra&apiKey=<your-api-key>&q=TWD_USD HTTP/1.1
    {
      "TWD_USD": "0.0312"
    }

Data categories

  • transactions
  • accounts
  • share-links
  • comments
  • subscriptions
  • fx-rates
  • e-invoices

Where teams use this data

  • Rebuild household P&L from cloud pages

    A tax or family-office job pages the cloud book, sums record_table.mount by category and date, and cross-checks amount_to_main so annual filings match the on-device ledger after a main-currency change.

  • Operate shared-book links

    A household bot lists share_links url_id / entity_hash_key / expired_at, loads nested records for each link, and posts comments on entity_hash_key so roommates can split a receipt without exchanging the whole SQLite file.

  • Watch Plus/Pro quota

    A sync watchdog reads plan, record_limit and usage.record against all_limits.plus / all_limits.pro and pauses upload insert batches before the cloud rejects new rows.

  • Ingest Taiwan carrier invoices

    A receipt pipeline pulls carrier invNum, sellerBan, sellerName and details.amount, then writes receipt_num and mount onto the matching out_payment so the household book stays aligned with MOF invoices.

Frequently asked questions

What sits in an AndroMoney cloud download?

A paged JSON object with total_pages plus table keys such as record_table, image_table, payment_table and carrier_table. Each table has delete and update arrays. Ledger rows use the wire name mount (not amount) plus amount_to_main, hash_key, sub_category, receipt_num, in_payment and out_payment. carrier_table is keyed by card_no.

How do shared books work?

Creating a link posts hash_keys and returns url_id. Listing returns share_links you own and links_share_to_me. Loading a link pages nested records with category, subcategory, payments, currency, comments and images. entity_type is Record or Project; secrecy and permission control visibility. Opening a shared link launches the book in the app.

Does AndroMoney connect to a bank?

No bank connection is used. Payments are local accounts (cash, EasyCard, bank nicknames) synced as payment_table. Taiwan e-invoices come from the Ministry of Finance carrier and barcode services (invNum, sellerBan). FX rates come from a currency-pair lookup. Plus/Pro status is plan, record_limit and usage on the AndroMoney subscription object.

Which fields identify a ledger row?

hash_key is the stable id across devices. mount is the signed amount; amount_to_main is that amount in the book’s main currency. receipt_num stores a Taiwan invoice number when the row was ingested from a carrier or QR scan. status 10/20/30 are income, expense and transfer.

Apps similar to AndroMoney

  • Money Manager Expense & Budget — Money Manager Expense & Budget by Realbyte records income and expenses with double-entry bookkeeping, graphs budget versus spending, and tracks credit-card settlement dates.
  • Bluecoins — Bluecoins is an expense-and-budget app that tracks income and expenses, plans budgets, and syncs a shared book over Google Drive, Dropbox or OneDrive.
  • Money Lover — Money Lover is an expense-tracker and money-manager app that records daily spending and income by category, sets budgets, and syncs across devices, with recurring bills and multi-currency support.
  • Monefy — Monefy is an expense tracker and household budget planner that logs purchases, charts spending, supports multiple accounts and currencies, and can share a budget across devices.
  • Wallet: Budget Expense Tracker — Wallet by BudgetBakers is a personal-finance manager that connects bank accounts to track expenses, sets custom budgets, and can share accounts with family.
  • YNAB — YNAB (You Need A Budget) is a personal-budgeting app for iOS, Android and the web that lets people assign money to categories before they spend and can import transactions by linking financial accounts.
  • Spendee — Spendee is a money-management app that tracks cash, bank accounts, e-wallets and crypto wallets, sets category budgets, and offers shared wallets for couples, families and roommates.
  • Cashew — Cashew is an expense and budget tracker that logs income and spending, supports weekly or monthly budgets and multiple currencies, and can back up the on-device book to Google Drive.

Topics

  • AndroMoney API
  • record_table mount
  • amount_to_main
  • share_links url_id
  • Taiwan e-invoice invNum
  • KPMoney ledger
  • 電子發票
  • hash_key

Need this app's data API integrated?

We deliver scoped integrations for any named app — from USD 500 with source-code handoff, or hosted access billed per call. Tell us the data you need.

  • NDA + SOW on every engagement
  • Delivery in 3–7 days
  • Payment only after acceptance
  • Work scoped to authorized use

Get a quote