SaaSMon logo

SaaSMon / Docs / API

API reference

Read and write your SaaSMon data from scripts, spreadsheets, Zapier/Make, or your own dashboards. The API is JSON over HTTPS and uses the same data you see in the app.

Base URL
https://api.saasmon.net/api/v1
Auth
X-Api-Key: sm_live_…
Version
v1 (in the URL). Breaking changes ship as a new version.

Quickstart

  1. In the dashboard, open API keys and create a key. Copy it — it's shown once.
  2. Store it as an environment variable, e.g. SAASMON_API_KEY.
  3. List your projects, then use a project id for everything else:
curl "https://api.saasmon.net/api/v1/projects" -H "X-Api-Key: $SAASMON_API_KEY"

Authentication

Send your key in the X-Api-Key header. Authorization: Bearer sm_live_…also works. Requests act as the account that owns the key and only see that account's data.

Key typeCan doPlans
Read onlyAll GET endpointsFree (1 key), Pro (up to 20)
Read & writeEverything below, including create, update and deletePro (up to 20)

Keys can't reach billing, account settings, notification preferences, uploads or key management — use the dashboard for those. Revoking a key takes effect on the next request. Keys can be given an expiry date when created.

Conventions

  • Request and response bodies are JSON (Content-Type: application/json), field names in camelCase.
  • Dates are ISO 8601 in UTC, e.g. 2026-10-28T00:00:00Z.
  • Amounts are decimal numbers in your account currency (set in Preferences). Always positive; type says whether money came in or went out.
  • Enums are strings: Income/Expenses, Paid/Pending, Weekly/Monthly/Quarterly/Yearly.
  • Lists return { items, totalCount } and accept page (1-based) and pageSize.
  • Ids are UUIDs.

Errors

Errors use standard status codes and a consistent body:

400Validation failed, or a referenced record doesn't exist or isn't yours (errorCode ERR_0001_DATA_NOT_FOUND). Plan limits also return 400 with a specific errorCode.
401Missing, invalid, expired or revoked key.
403The key is read-only, or the endpoint isn't available to API keys.
429Rate limit exceeded. Wait for the Retry-After seconds.
500Something broke on our side. Safe to retry GET requests; include traceId if you contact support.
{
  "statusCode": 400,
  "message": "One or more validation errors occurred.",
  "errors": [
    {
      "propertyName": "netAmount",
      "errorCode": "GreaterThanValidator",
      "errorMessage": "'Net Amount' must be greater than '0'."
    }
  ],
  "traceId": "00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01"
}

Rate limits

Each key can make 120 requests per minute. Over the limit you get 429 with a Retry-Afterheader. Limits are per key, so a busy integration doesn't slow down another.

Guidelines

  • Keep keys server-side. Never ship a key in browser or mobile code, and don't commit it to git.
  • Use the least access you need. Reporting and dashboards only need a read-only key.
  • One key per integration. Name keys after what uses them, so revoking one doesn't break the others.
  • Rotate. Set an expiry, create the replacement first, switch over, then revoke the old key.
  • Prefer reports over raw data. /reports/overview and /reports/forecast already compute MRR, burn and runway.
  • Batch writes. Use import (up to 5,000 rows) and bulk actions instead of thousands of single calls.
  • Avoid duplicates. Before creating, list with dateFrom/dateTo and search to check the entry isn't already there.
  • Back off on 429 and 5xx. Retry with exponential backoff; respect Retry-After.

Projects

A project is one product or business. Everything else belongs to a project.

List projects

GET/projects

All projects owned by the key's account.

Query parameters

searchstringFilter by name.
pageinteger1-based page number. Default 1.
pageSizeintegerItems per page. Default 20.
sortBystringField to sort by (see endpoint).
sortDescbooleanSort descending when true.
curl "https://api.saasmon.net/api/v1/projects" \
  -H "X-Api-Key: $SAASMON_API_KEY"

Response

{
  "items": [
    {
      "id": "9c1d2e3f-4a5b-4c6d-8e7f-0a1b2c3d4e5f",
      "name": "Quillpad",
      "description": "Markdown notes for teams",
      "logo": null
    }
  ],
  "totalCount": 1
}

Get a project

GET/projects/{id}

A single project by id.

Path parameters

iduuidrequiredThe project id.
curl "https://api.saasmon.net/api/v1/projects/ID" \
  -H "X-Api-Key: $SAASMON_API_KEY"

Response

{
  "id": "9c1d2e3f-4a5b-4c6d-8e7f-0a1b2c3d4e5f",
  "name": "Quillpad",
  "description": "Markdown notes for teams",
  "logo": null
}

Create a project

POST/projectsneeds a read & write key

Counts toward your plan's project limit.

Body (JSON)

namestringrequiredProject name.
descriptionstringUp to 255 characters.
logostringImage URL.
curl -X POST "https://api.saasmon.net/api/v1/projects" \
  -H "X-Api-Key: $SAASMON_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name":"Tallyform","description":"Form builder"}'

Response

{
  "id": "9c1d2e3f-4a5b-4c6d-8e7f-0a1b2c3d4e5f",
  "name": "Tallyform",
  "description": "Form builder",
  "logo": null
}

Transactions

Income and expense entries. Amounts are decimals in your account currency.

List transactions

GET/projects/{projectId}/transactions

Filter, search and page through a project's transactions.

Path parameters

projectIduuidrequiredThe project id.

Query parameters

typeenumIncome | Expenses
statusenumPaid | Pending
categoryIduuidOnly this category.
accountTypeIduuidOnly this account.
dateFromdatetimeInclusive lower bound.
dateTodatetimeInclusive upper bound.
searchstringMatches description.
pageinteger1-based page number. Default 1.
pageSizeintegerItems per page. Default 20.
sortBystringdate | originalAmount | netAmount (default: created)
sortDescbooleanSort descending when true.
curl "https://api.saasmon.net/api/v1/projects/PROJECT_ID/transactions" \
  -H "X-Api-Key: $SAASMON_API_KEY"

Response

{
  "items": [
    {
      "id": "3f2b7c1e-8a4d-4f6e-9b21-5c0d7e9a1f34",
      "projectId": "9c1d2e3f-4a5b-4c6d-8e7f-0a1b2c3d4e5f",
      "date": "2026-10-28T00:00:00Z",
      "description": "Stripe payout",
      "categoryId": "b7e8f9a0-1b2c-4d3e-8f4a-5b6c7d8e9f01",
      "categoryName": "Subscriptions",
      "categoryIconKey": "repeat",
      "status": "Paid",
      "originalAmount": 1250,
      "netAmount": 1213.45,
      "type": "Income",
      "accountTypeId": "e1f2a3b4-c5d6-4e7f-8a9b-0c1d2e3f4a5b",
      "accountTypeName": "Stripe"
    }
  ],
  "totalCount": 214
}

Get a transaction

GET/transactions/{id}

A single transaction by id.

Path parameters

iduuidrequiredThe transaction id.
curl "https://api.saasmon.net/api/v1/transactions/ID" \
  -H "X-Api-Key: $SAASMON_API_KEY"

Response

{
  "id": "3f2b7c1e-8a4d-4f6e-9b21-5c0d7e9a1f34",
  "projectId": "9c1d2e3f-4a5b-4c6d-8e7f-0a1b2c3d4e5f",
  "date": "2026-10-28T00:00:00Z",
  "description": "Stripe payout",
  "categoryId": "b7e8f9a0-1b2c-4d3e-8f4a-5b6c7d8e9f01",
  "categoryName": "Subscriptions",
  "categoryIconKey": "repeat",
  "status": "Paid",
  "originalAmount": 1250,
  "netAmount": 1213.45,
  "type": "Income",
  "accountTypeId": "e1f2a3b4-c5d6-4e7f-8a9b-0c1d2e3f4a5b",
  "accountTypeName": "Stripe"
}

Create a transaction

POST/transactionsneeds a read & write key

Record one income or expense entry.

Body (JSON)

projectIduuidrequiredTarget project.
datedatetimerequiredISO 8601, e.g. 2026-10-28T00:00:00Z.
typeenumrequiredIncome | Expenses
descriptionstringFree text, shown in lists and exports.
categoryIduuidrequiredA category of the same type in this project.
accountTypeIduuidrequiredAn account in this project.
statusenumrequiredPaid | Pending. Only Paid counts toward balance.
originalAmountdecimalrequiredGross amount, > 0.
netAmountdecimalrequiredAmount after fees, > 0. Reports use this.
curl -X POST "https://api.saasmon.net/api/v1/transactions" \
  -H "X-Api-Key: $SAASMON_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"projectId":"9c1d2e3f-4a5b-4c6d-8e7f-0a1b2c3d4e5f","date":"2026-10-28T00:00:00Z","type":"Income","description":"Stripe payout","categoryId":"b7e8f9a0-1b2c-4d3e-8f4a-5b6c7d8e9f01","accountTypeId":"e1f2a3b4-c5d6-4e7f-8a9b-0c1d2e3f4a5b","status":"Paid","originalAmount":1250,"netAmount":1213.45}'

Response

{
  "id": "3f2b7c1e-8a4d-4f6e-9b21-5c0d7e9a1f34",
  "projectId": "9c1d2e3f-4a5b-4c6d-8e7f-0a1b2c3d4e5f",
  "date": "2026-10-28T00:00:00Z",
  "description": "Stripe payout",
  "categoryId": "b7e8f9a0-1b2c-4d3e-8f4a-5b6c7d8e9f01",
  "categoryName": "Subscriptions",
  "categoryIconKey": "repeat",
  "status": "Paid",
  "originalAmount": 1250,
  "netAmount": 1213.45,
  "type": "Income",
  "accountTypeId": "e1f2a3b4-c5d6-4e7f-8a9b-0c1d2e3f4a5b",
  "accountTypeName": "Stripe"
}

Update a transaction

PUT/transactions/{id}needs a read & write key

Replace all editable fields.

Path parameters

iduuidrequiredThe transaction id.

Body (JSON)

datedatetimerequiredISO 8601, e.g. 2026-10-28T00:00:00Z.
typeenumrequiredIncome | Expenses
descriptionstringFree text, shown in lists and exports.
categoryIduuidrequiredA category of the same type in this project.
accountTypeIduuidrequiredAn account in this project.
statusenumrequiredPaid | Pending. Only Paid counts toward balance.
originalAmountdecimalrequiredGross amount, > 0.
netAmountdecimalrequiredAmount after fees, > 0. Reports use this.
curl -X PUT "https://api.saasmon.net/api/v1/transactions/ID" \
  -H "X-Api-Key: $SAASMON_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"date":"2026-10-28T00:00:00Z","type":"Income","description":"Stripe payout (corrected)","categoryId":"b7e8f9a0-1b2c-4d3e-8f4a-5b6c7d8e9f01","accountTypeId":"e1f2a3b4-c5d6-4e7f-8a9b-0c1d2e3f4a5b","status":"Paid","originalAmount":1250,"netAmount":1210}'

Response

{
  "id": "3f2b7c1e-8a4d-4f6e-9b21-5c0d7e9a1f34",
  "projectId": "9c1d2e3f-4a5b-4c6d-8e7f-0a1b2c3d4e5f",
  "date": "2026-10-28T00:00:00Z",
  "description": "Stripe payout (corrected)",
  "categoryId": "b7e8f9a0-1b2c-4d3e-8f4a-5b6c7d8e9f01",
  "categoryName": "Subscriptions",
  "categoryIconKey": "repeat",
  "status": "Paid",
  "originalAmount": 1250,
  "netAmount": 1210,
  "type": "Income",
  "accountTypeId": "e1f2a3b4-c5d6-4e7f-8a9b-0c1d2e3f4a5b",
  "accountTypeName": "Stripe"
}

Delete a transaction

DELETE/transactions/{id}needs a read & write key

Returns 204 No Content.

Path parameters

iduuidrequiredThe transaction id.
curl -X DELETE "https://api.saasmon.net/api/v1/transactions/ID" \
  -H "X-Api-Key: $SAASMON_API_KEY"

Returns 204 No Content.

Bulk update or delete

POST/projects/{projectId}/transactions/bulkneeds a read & write key

Apply one action to up to 1,000 transactions.

Path parameters

projectIduuidrequiredThe project id.

Body (JSON)

idsuuid[]requiredTransaction ids (max 1,000).
actionenumrequireddelete | mark-paid | mark-pending
curl -X POST "https://api.saasmon.net/api/v1/projects/PROJECT_ID/transactions/bulk" \
  -H "X-Api-Key: $SAASMON_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"ids":["3f2b7c1e-8a4d-4f6e-9b21-5c0d7e9a1f34"],"action":"mark-paid"}'

Response

{
  "affected": 1
}

Import transactions

POST/projects/{projectId}/transactions/importneeds a read & write key

Create up to 5,000 transactions in one call. Unknown category and account names are created. Paid plans only.

Path parameters

projectIduuidrequiredThe project id.

Body (JSON)

rows[].datedatetimerequiredTransaction date.
rows[].typeenumrequiredIncome | Expenses
rows[].descriptionstringFree text.
rows[].categoryNamestringMatched by name; defaults to Uncategorized.
rows[].accountTypeNamestringMatched by name; defaults to the first account.
rows[].statusenumrequiredPaid | Pending
rows[].originalAmountdecimalrequired> 0.
rows[].netAmountdecimalDefaults to originalAmount.
curl -X POST "https://api.saasmon.net/api/v1/projects/PROJECT_ID/transactions/import" \
  -H "X-Api-Key: $SAASMON_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"rows":[{"date":"2026-10-01T00:00:00Z","type":"Expenses","description":"Hetzner CX32","categoryName":"Hosting","accountTypeName":"Business bank","status":"Paid","originalAmount":18.5}]}'

Response

{
  "imported": 1,
  "categoriesCreated": 0,
  "accountTypesCreated": 0
}

Export as CSV

GET/projects/{projectId}/transactions/export

UTF-8 CSV with columns date, type, description, category, account, status, original_amount, net_amount.

Path parameters

projectIduuidrequiredThe project id.

Query parameters

typeenumIncome | Expenses
dateFromdatetimeInclusive lower bound.
dateTodatetimeInclusive upper bound.
curl "https://api.saasmon.net/api/v1/projects/PROJECT_ID/transactions/export" \
  -H "X-Api-Key: $SAASMON_API_KEY"

Response

date,type,description,category,account,status,original_amount,net_amount
2026-10-28,income,Stripe payout,Subscriptions,Stripe,paid,1250.00,1213.45

Recurring transactions

Rules that post a transaction automatically every week, month, quarter or year.

List recurring rules

GET/projects/{projectId}/recurring-transactions

Includes monthly run-rate totals.

Path parameters

projectIduuidrequiredThe project id.

Query parameters

typeenumIncome | Expenses
isActivebooleanOnly active or paused rules.
curl "https://api.saasmon.net/api/v1/projects/PROJECT_ID/recurring-transactions" \
  -H "X-Api-Key: $SAASMON_API_KEY"

Response

{
  "items": [
    {
      "id": "3f2b7c1e-8a4d-4f6e-9b21-5c0d7e9a1f34",
      "projectId": "9c1d2e3f-4a5b-4c6d-8e7f-0a1b2c3d4e5f",
      "description": "Vercel Pro",
      "type": "Expenses",
      "status": "Paid",
      "originalAmount": 20,
      "netAmount": 20,
      "frequency": "Monthly",
      "startDate": "2026-01-05T00:00:00Z",
      "endDate": null,
      "nextRunDate": "2026-11-05T00:00:00Z",
      "lastRunDate": "2026-10-05T00:00:00Z",
      "isActive": true,
      "occurrenceCount": 10,
      "monthlyAmount": 20,
      "categoryId": "b7e8f9a0-1b2c-4d3e-8f4a-5b6c7d8e9f01",
      "categoryName": "Hosting",
      "categoryIconKey": "server",
      "accountTypeId": "e1f2a3b4-c5d6-4e7f-8a9b-0c1d2e3f4a5b",
      "accountTypeName": "Business bank"
    }
  ],
  "totalCount": 1,
  "monthlyRecurringIncome": 4820,
  "monthlyRecurringExpenses": 20
}

Create a recurring rule

POST/recurring-transactionsneeds a read & write key

Occurrences from startDate up to now are posted immediately. Free plans allow 3 rules.

Body (JSON)

projectIduuidrequiredTarget project.
descriptionstringrequiredName shown on posted transactions.
typeenumrequiredIncome | Expenses
statusenumrequiredStatus of posted transactions: Paid | Pending
originalAmountdecimalrequired> 0.
netAmountdecimalrequired> 0.
frequencyenumrequiredWeekly | Monthly | Quarterly | Yearly
startDatedatetimerequiredFirst occurrence.
endDatedatetimeLast possible occurrence. Omit for no end.
categoryIduuidrequiredCategory of the same type.
accountTypeIduuidrequiredAccount in this project.
curl -X POST "https://api.saasmon.net/api/v1/recurring-transactions" \
  -H "X-Api-Key: $SAASMON_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"projectId":"9c1d2e3f-4a5b-4c6d-8e7f-0a1b2c3d4e5f","description":"Vercel Pro","type":"Expenses","status":"Paid","originalAmount":20,"netAmount":20,"frequency":"Monthly","startDate":"2026-11-05T00:00:00Z","categoryId":"b7e8f9a0-1b2c-4d3e-8f4a-5b6c7d8e9f01","accountTypeId":"e1f2a3b4-c5d6-4e7f-8a9b-0c1d2e3f4a5b"}'

Response

{
  "id": "3f2b7c1e-8a4d-4f6e-9b21-5c0d7e9a1f34",
  "projectId": "9c1d2e3f-4a5b-4c6d-8e7f-0a1b2c3d4e5f",
  "description": "Vercel Pro",
  "type": "Expenses",
  "status": "Paid",
  "originalAmount": 20,
  "netAmount": 20,
  "frequency": "Monthly",
  "startDate": "2026-01-05T00:00:00Z",
  "endDate": null,
  "nextRunDate": "2026-11-05T00:00:00Z",
  "lastRunDate": "2026-10-05T00:00:00Z",
  "isActive": true,
  "occurrenceCount": 10,
  "monthlyAmount": 20,
  "categoryId": "b7e8f9a0-1b2c-4d3e-8f4a-5b6c7d8e9f01",
  "categoryName": "Hosting",
  "categoryIconKey": "server",
  "accountTypeId": "e1f2a3b4-c5d6-4e7f-8a9b-0c1d2e3f4a5b",
  "accountTypeName": "Business bank"
}

Update or pause a rule

PUT/recurring-transactions/{id}needs a read & write key

Same body as create (without projectId), plus isActive to pause or resume.

Path parameters

iduuidrequiredThe rule id.

Body (JSON)

isActivebooleanfalse pauses the rule.
curl -X PUT "https://api.saasmon.net/api/v1/recurring-transactions/ID" \
  -H "X-Api-Key: $SAASMON_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"description":"Vercel Pro","type":"Expenses","status":"Paid","originalAmount":20,"netAmount":20,"frequency":"Monthly","startDate":"2026-01-05T00:00:00Z","categoryId":"b7e8f9a0-1b2c-4d3e-8f4a-5b6c7d8e9f01","accountTypeId":"e1f2a3b4-c5d6-4e7f-8a9b-0c1d2e3f4a5b","isActive":false}'

Response

{
  "id": "3f2b7c1e-8a4d-4f6e-9b21-5c0d7e9a1f34",
  "projectId": "9c1d2e3f-4a5b-4c6d-8e7f-0a1b2c3d4e5f",
  "description": "Vercel Pro",
  "type": "Expenses",
  "status": "Paid",
  "originalAmount": 20,
  "netAmount": 20,
  "frequency": "Monthly",
  "startDate": "2026-01-05T00:00:00Z",
  "endDate": null,
  "nextRunDate": "2026-11-05T00:00:00Z",
  "lastRunDate": "2026-10-05T00:00:00Z",
  "isActive": false,
  "occurrenceCount": 10,
  "monthlyAmount": 20,
  "categoryId": "b7e8f9a0-1b2c-4d3e-8f4a-5b6c7d8e9f01",
  "categoryName": "Hosting",
  "categoryIconKey": "server",
  "accountTypeId": "e1f2a3b4-c5d6-4e7f-8a9b-0c1d2e3f4a5b",
  "accountTypeName": "Business bank"
}

Delete a rule

DELETE/recurring-transactions/{id}needs a read & write key

Stops future occurrences. Already-posted transactions are kept. Returns 204.

Path parameters

iduuidrequiredThe rule id.
curl -X DELETE "https://api.saasmon.net/api/v1/recurring-transactions/ID" \
  -H "X-Api-Key: $SAASMON_API_KEY"

Returns 204 No Content.

Reports

Pre-computed numbers for dashboards, digests and spreadsheets.

Project overview

GET/projects/{projectId}/reports/overview

Totals, KPIs (MRR, ARR, burn, margin, CAC, LTV, churn), daily trend, category breakdowns and budgets for a date range.

Path parameters

projectIduuidrequiredThe project id.

Query parameters

dateFromdatetimeDefaults to all time.
dateTodatetimeDefaults to now.
curl "https://api.saasmon.net/api/v1/projects/PROJECT_ID/reports/overview" \
  -H "X-Api-Key: $SAASMON_API_KEY"

Response

{
  "projectId": "9c1d2e3f-4a5b-4c6d-8e7f-0a1b2c3d4e5f",
  "totals": {
    "totalIncome": 6420,
    "totalExpenses": 2310,
    "pendingIncome": 120,
    "pendingExpenses": 40,
    "net": 4110
  },
  "previousTotals": {
    "totalIncome": 5900,
    "totalExpenses": 2310,
    "pendingIncome": 120,
    "pendingExpenses": 40,
    "net": 3400
  },
  "kpis": {
    "mrr": 4820,
    "arr": 57840,
    "cac": 32,
    "growthPercent": 6.1,
    "burnRate": 2310,
    "profitMarginPercent": 64,
    "churnPercent": 2.4,
    "ltv": 410
  },
  "trend": [
    {
      "date": "2026-10-28T00:00:00Z",
      "income": 210,
      "expenses": 64,
      "net": 146
    }
  ],
  "expenseDistribution": [
    {
      "categoryId": "b7e8f9a0-1b2c-4d3e-8f4a-5b6c7d8e9f01",
      "categoryName": "Hosting",
      "amount": 900
    }
  ],
  "…": "incomeByCategory, accountTypeBalances, heatmap, recentActivities, budgetComparison"
}

Portfolio overview

GET/reports/portfolio-overview

Totals and trend across every project, plus a per-project summary.

Query parameters

dateFromdatetimeDefaults to all time.
dateTodatetimeDefaults to now.
curl "https://api.saasmon.net/api/v1/reports/portfolio-overview" \
  -H "X-Api-Key: $SAASMON_API_KEY"

Response

{
  "totals": {
    "totalIncome": 6420,
    "totalExpenses": 2310,
    "pendingIncome": 120,
    "pendingExpenses": 40,
    "net": 4110
  },
  "previousTotals": {
    "totalIncome": 6420,
    "totalExpenses": 2310,
    "pendingIncome": 120,
    "pendingExpenses": 40,
    "net": 4110
  },
  "trend": [],
  "projectSummaries": [
    {
      "projectId": "9c1d2e3f-4a5b-4c6d-8e7f-0a1b2c3d4e5f",
      "projectName": "Quillpad",
      "totals": {
        "totalIncome": 6420,
        "totalExpenses": 2310,
        "pendingIncome": 120,
        "pendingExpenses": 40,
        "net": 4110
      },
      "previousTotals": {
        "totalIncome": 6420,
        "totalExpenses": 2310,
        "pendingIncome": 120,
        "pendingExpenses": 40,
        "net": 4110
      }
    }
  ]
}

Cash-flow forecast

GET/projects/{projectId}/reports/forecast

Current balance projected forward from active recurring rules. runwayMonths is null when cash-flow positive.

Path parameters

projectIduuidrequiredThe project id.

Query parameters

monthsintegerHorizon, 1–24. Default 6.
curl "https://api.saasmon.net/api/v1/projects/PROJECT_ID/reports/forecast" \
  -H "X-Api-Key: $SAASMON_API_KEY"

Response

{
  "currentBalance": 18400,
  "monthlyRecurringIncome": 4820,
  "monthlyRecurringExpenses": 2900,
  "averageMonthlyNet": 1500,
  "runwayMonths": null,
  "points": [
    {
      "month": "2026-11-01T00:00:00Z",
      "income": 4820,
      "expenses": 2900,
      "net": 1920,
      "balance": 20320
    }
  ]
}

Categories, accounts & budgets

The building blocks transactions point to.

List categories

GET/projects/{projectId}/categories

Income and expense categories.

Path parameters

projectIduuidrequiredThe project id.

Query parameters

typeenumIncome | Expenses
searchstringFilter by name.
pageinteger1-based page number. Default 1.
pageSizeintegerItems per page. Default 20.
sortBystringField to sort by (see endpoint).
sortDescbooleanSort descending when true.
curl "https://api.saasmon.net/api/v1/projects/PROJECT_ID/categories" \
  -H "X-Api-Key: $SAASMON_API_KEY"

Response

{
  "items": [
    {
      "id": "b7e8f9a0-1b2c-4d3e-8f4a-5b6c7d8e9f01",
      "projectId": "9c1d2e3f-4a5b-4c6d-8e7f-0a1b2c3d4e5f",
      "name": "Hosting",
      "description": null,
      "orderIndex": 0,
      "type": "Expenses",
      "iconKey": "server"
    }
  ],
  "totalCount": 1
}

Create a category

POST/categoriesneeds a read & write key

Body (JSON)

projectIduuidrequiredTarget project.
namestringrequiredCategory name.
typeenumrequiredIncome | Expenses
descriptionstringOptional.
iconKeystringOptional icon identifier.
curl -X POST "https://api.saasmon.net/api/v1/categories" \
  -H "X-Api-Key: $SAASMON_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"projectId":"9c1d2e3f-4a5b-4c6d-8e7f-0a1b2c3d4e5f","name":"Hosting","type":"Expenses"}'

Response

{
  "id": "b7e8f9a0-1b2c-4d3e-8f4a-5b6c7d8e9f01",
  "projectId": "9c1d2e3f-4a5b-4c6d-8e7f-0a1b2c3d4e5f",
  "name": "Hosting",
  "description": null,
  "orderIndex": 0,
  "type": "Expenses",
  "iconKey": null
}

List accounts

GET/projects/{projectId}/account-types

Where money sits: bank, Stripe balance, card, cash.

Path parameters

projectIduuidrequiredThe project id.

Query parameters

searchstringFilter by name.
pageinteger1-based page number. Default 1.
pageSizeintegerItems per page. Default 20.
sortBystringField to sort by (see endpoint).
sortDescbooleanSort descending when true.
curl "https://api.saasmon.net/api/v1/projects/PROJECT_ID/account-types" \
  -H "X-Api-Key: $SAASMON_API_KEY"

Response

{
  "items": [
    {
      "id": "e1f2a3b4-c5d6-4e7f-8a9b-0c1d2e3f4a5b",
      "projectId": "9c1d2e3f-4a5b-4c6d-8e7f-0a1b2c3d4e5f",
      "name": "Stripe",
      "description": null,
      "orderIndex": 0
    }
  ],
  "totalCount": 1
}

Create an account

POST/account-typesneeds a read & write key

Body (JSON)

projectIduuidrequiredTarget project.
namestringrequiredAccount name.
descriptionstringOptional.
curl -X POST "https://api.saasmon.net/api/v1/account-types" \
  -H "X-Api-Key: $SAASMON_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"projectId":"9c1d2e3f-4a5b-4c6d-8e7f-0a1b2c3d4e5f","name":"Business bank"}'

Response

{
  "id": "e1f2a3b4-c5d6-4e7f-8a9b-0c1d2e3f4a5b",
  "projectId": "9c1d2e3f-4a5b-4c6d-8e7f-0a1b2c3d4e5f",
  "name": "Business bank",
  "description": null,
  "orderIndex": 1
}

List budgets

GET/projects/{projectId}/budgets

Each budget includes spent, remaining and usage percent.

Path parameters

projectIduuidrequiredThe project id.

Query parameters

categoryIduuidOnly this category.
startDateFromdatetimeBudgets starting on/after.
startDateTodatetimeBudgets starting on/before.
pageinteger1-based page number. Default 1.
pageSizeintegerItems per page. Default 20.
sortBystringField to sort by (see endpoint).
sortDescbooleanSort descending when true.
curl "https://api.saasmon.net/api/v1/projects/PROJECT_ID/budgets" \
  -H "X-Api-Key: $SAASMON_API_KEY"

Response

{
  "items": [
    {
      "id": "3f2b7c1e-8a4d-4f6e-9b21-5c0d7e9a1f34",
      "projectId": "9c1d2e3f-4a5b-4c6d-8e7f-0a1b2c3d4e5f",
      "categoryId": "b7e8f9a0-1b2c-4d3e-8f4a-5b6c7d8e9f01",
      "categoryName": "Marketing",
      "amount": 1000,
      "startDate": "2026-11-01T00:00:00Z",
      "endDate": "2026-11-30T23:59:59Z",
      "spentAmount": 700,
      "remainingAmount": 300,
      "usagePercent": 70
    }
  ],
  "totalCount": 1
}

Need something the API doesn't do yet?

Tell us what you're building at [email protected]. Webhooks and per-project keys are on the roadmap.