MoneySheets API
The MoneySheets API lets you read the financial data MoneySheets syncs into your Google Sheet β transactions, categories, and categorization rules β and control how and when that data is synced.
It is a small, predictable REST API. All requests are made over HTTPS, authenticated with a personal API token, and all responses are JSON.
Every endpoint is scoped to a single MoneySheets account: the token you send determines whose data you read and write.
Prefer to explore interactively? Try it in Swagger β sign-in required.
Authentication
The API authenticates with a personal API token. Create one in the dashboard under API tokens β you will see the token value once, so copy it somewhere safe.
Send the token in the Authorization header as a bearer token on every request. Tokens always start with the prefix ms_.
Each token carries one or more scopes. The read scope grants access to the GET endpoints (transactions, categories, rules, schedule). The write scope is required to trigger a sync or change your schedule. Requesting an endpoint without the required scope returns 403.
curl https://moneysheets.io/api/v2/transactions \
-H "Authorization: Bearer ms_your_token_here"Base URL
All endpoints live under the https://moneysheets.io/api/v2 base path. Paths in this reference are written relative to that base.
Requests must use HTTPS. Plain HTTP requests are redirected.
https://moneysheets.io/api/v2Errors
The API uses conventional HTTP status codes. Any non-2xx response has a JSON body with a single error field describing what went wrong.
{
"error": "Authentication required"
}| Status | Meaning |
|---|---|
| 400 Bad Request | A parameter is malformed β for example an invalid date or an invalid schedule payload. |
| 401 Unauthorized | The Authorization header is missing, or the token is invalid or revoked. |
| 403 Forbidden | The token lacks the scope the endpoint requires, or the action needs an active subscription. |
| 429 Too Many Requests | The sync rate limit has been reached. Wait before retrying. |
Rate limits
The sync endpoint is rate limited to protect the underlying Google Sheets integration. When you exceed the limit the API returns 429; wait a short while before retrying.
The read endpoints are not rate limited under normal use, but please avoid tight polling loops β the data changes at most a few times a day.
List transactions
/api/v2/transactionsread scopeReturns the transactions synced to your sheet within a date range, keyed by a unique transaction id. When the same transaction id occurs more than once in the range, later occurrences are suffixed with #2, #3, and so on.
Query parameters
| Field | Type | Description |
|---|---|---|
start_date | string | Inclusive start date, YYYY-MM-DD. Defaults to 30 days ago. |
end_date | string | Inclusive end date, YYYY-MM-DD. Defaults to today. |
curl "https://moneysheets.io/api/v2/transactions?start_date=2026-01-01&end_date=2026-01-31" \
-H "Authorization: Bearer ms_your_token_here"{
"transactions": {
"a1b2c3": {
"row_index": 42,
"amount": "-24.90",
"date": "2026-01-14",
"date_added": "2026-01-15T03:12:00+00:00",
"account_id": "acc_123",
"bank_account_identifier": "Revolut EUR",
"sheet_description": "NETFLIX.COM",
"category": "Subscriptions"
}
},
"count": 1,
"start_date": "2026-01-01",
"end_date": "2026-01-31"
}Response fields
| Field | Type | Description |
|---|---|---|
transactionsrequired | object | Map of transaction id to a transaction object (fields below). |
countrequired | integer | Number of transactions returned. |
start_daterequired | string | The resolved start date of the range. |
end_daterequired | string | The resolved end date of the range. |
transactions[].amountrequired | string | Signed transaction amount. |
transactions[].daterequired | string | Transaction date as shown in the sheet. |
transactions[].date_addedrequired | string | ISO 8601 timestamp of when the row was added. |
transactions[].bank_account_identifierrequired | string | Identifier of the source bank account. |
transactions[].account_id | string | null | Provider account id, when available. |
transactions[].sheet_descriptionrequired | string | Transaction description. |
transactions[].categoryrequired | string | Assigned category, or empty if uncategorized. |
transactions[].row_indexrequired | integer | Row number in the underlying sheet. |
Errors
| Status | When |
|---|---|
| 400 | Invalid date format β dates must be YYYY-MM-DD. |
| 401 | Missing or invalid token. |
| 403 | The token lacks the read scope. |
List categories
/api/v2/categoriesread scopeReturns the list of categories defined in your sheet.
curl https://moneysheets.io/api/v2/categories \
-H "Authorization: Bearer ms_your_token_here"{
"categories": ["Groceries", "Rent", "Subscriptions", "Salary"]
}Response fields
| Field | Type | Description |
|---|---|---|
categoriesrequired | string[] | The category names, in sheet order. |
Errors
| Status | When |
|---|---|
| 401 | Missing or invalid token. |
| 403 | The token lacks the read scope. |
List rules
/api/v2/rulesread scopeReturns your categorization rules. Each rule maps a description pattern to a category, optionally constrained to an amount range.
curl https://moneysheets.io/api/v2/rules \
-H "Authorization: Bearer ms_your_token_here"{
"rules": [
{
"description": "NETFLIX",
"category": "Subscriptions",
"minAmount": "",
"maxAmount": ""
}
]
}Response fields
| Field | Type | Description |
|---|---|---|
rules[].descriptionrequired | string | Description pattern the rule matches on. |
rules[].categoryrequired | string | Category applied when the rule matches. |
rules[].minAmount | string | Lower bound of the amount range, or empty. |
rules[].maxAmount | string | Upper bound of the amount range, or empty. |
Errors
| Status | When |
|---|---|
| 401 | Missing or invalid token. |
| 403 | The token lacks the read scope. |
Sync transactions
/api/v2/sync-transactionswrite scopeTriggers a sync of the latest bank transactions into your sheet. The sync runs in the background; the response confirms it was scheduled.
curl -X POST https://moneysheets.io/api/v2/sync-transactions \
-H "Authorization: Bearer ms_your_token_here"{
"success": true,
"message": "Sync scheduled"
}Response fields
| Field | Type | Description |
|---|---|---|
successrequired | boolean | Whether the sync was scheduled. |
messagerequired | string | Human-readable status message. |
Errors
| Status | When |
|---|---|
| 401 | Missing or invalid token. |
| 403 | The token lacks the write scope, or the trial/subscription is inactive. |
| 429 | The sync rate limit has been reached. |
Get schedule
/api/v2/scheduleread scopeReturns your current automatic sync schedule.
curl https://moneysheets.io/api/v2/schedule \
-H "Authorization: Bearer ms_your_token_here"{
"active": true,
"start_time": "08:00",
"period_minutes": 1440,
"cron": "0 8 * * *",
"last_run_time": "2026-01-15T08:00:00+00:00"
}Response fields
| Field | Type | Description |
|---|---|---|
activerequired | boolean | Whether an automatic sync schedule is set. |
start_time | string | null | Time of the first run each cycle. |
period_minutes | integer | null | Interval between runs, in minutes. |
cron | string | null | The underlying cron expression. |
last_run_time | string | null | ISO 8601 timestamp of the last run. |
Errors
| Status | When |
|---|---|
| 401 | Missing or invalid token. |
| 403 | The token lacks the read scope. |
Set schedule
/api/v2/schedulewrite scopeCreates or updates the recurring sync schedule. start_time is the time of the first run; hours and minutes set the interval between runs.
Body parameters
| Field | Type | Description |
|---|---|---|
start_timerequired | string | Time of the first run, e.g. "08:00". |
hours | integer | Hours between runs. Defaults to 0. |
minutes | integer | Minutes between runs. Defaults to 0. |
curl -X POST https://moneysheets.io/api/v2/schedule \
-H "Authorization: Bearer ms_your_token_here" \
-H "Content-Type: application/json" \
-d '{"start_time": "08:00", "hours": 24, "minutes": 0}'{
"success": true
}Response fields
| Field | Type | Description |
|---|---|---|
successrequired | boolean | Whether the schedule was saved. |
Errors
| Status | When |
|---|---|
| 400 | The schedule payload is invalid. |
| 401 | Missing or invalid token. |
| 403 | The token lacks the write scope. |
Cancel schedule
/api/v2/schedulewrite scopeRemoves the recurring sync schedule. Automatic syncs stop; you can still sync manually.
curl -X DELETE https://moneysheets.io/api/v2/schedule \
-H "Authorization: Bearer ms_your_token_here"{
"success": true
}Response fields
| Field | Type | Description |
|---|---|---|
successrequired | boolean | Whether the schedule was cancelled. |
Errors
| Status | When |
|---|---|
| 401 | Missing or invalid token. |
| 403 | The token lacks the write scope. |