List business plan goals vs actuals
accounting:cashflow.readhttps://api.holded.com/api/v2/business-plan/goalsReturns Business Plan goals for the authenticated account, one row per accounting account, broken down by month. Each month carries both the `goal` (the target the account set for itself) and the `actual` (what really happened, from the ledger) for the same period, so goal and reality can be compared without a second call. Use when the user wants to compare a client's Business Plan targets against what actually happened, e.g. to prepare a monthly review. Only `tree=profit_and_loss` is supported today; Cashflow goals are not available through this endpoint yet. `start_date` must not be after `end_date`, and the range between them must not exceed 36 months. Returns an empty list, not an error, when the account has no Business Plan configured or no goals exist in the requested range.
Parameters
Query parameters
string<date>requiredStart of the reporting range (inclusive, snapped to the first day of its month)
string<date>requiredEnd of the reporting range (inclusive — any day within the last desired month)
stringrequiredGoal tree to query. Only "profit_and_loss" is supported today.
"profit_and_loss"stringoptionalBusiness Plan scenario to query — see GET /api/v2/business-plan/scenarios. Defaults to the account's main scenario.
stringoptionalRestrict the response to a single accounting account. Omit to return every account in the tree.
booleanoptional= falseWhen true, excludes accounting accounts with no goal set anywhere in the requested range. Without it, a chart of accounts with few goals mostly returns rows with goal: null — this filters those out before pagination, so pages are not spent on empty accounts.
stringoptionalOpaque cursor for pagination
integeroptional= 50Maximum number of accounting accounts to return per page. Defaults to 50, maximum 200.
Request
import requests
url = "https://api.holded.com/api/v2/business-plan/goals?start_date=2026-01-01&end_date=2026-12-31&tree=profit_and_loss"
headers = {
"Authorization": "Bearer YOUR_API_KEY",
"Accept": "application/json",
}
response = requests.get(url, headers=headers)
print(response.json())Responses
Response
{
"items": [
{
"accounting_account_id": "507f1f77bcf86cd799439011",
"accounting_account_number": 70500001,
"accounting_account_name": "Ventas",
"months": [
{
"month": "...",
"goal": "...",
"actual": "..."
}
]
}
],
"cursor": "string",
"has_more": true
}Success responses
200List of business plan goals vs actuals, by accounting accountapplication/jsonIdentifier of the accounting account
Chart of accounts number
Name of the accounting account
One entry per month in the requested range, always present even when both goal and actual are empty for that month
Opaque cursor pointing to the next page. Pass as `cursor` in the next request. Null when there is no next page.
Whether more pages are available after this one
Error responses
400Invalid tree, date range or identifierapplication/json401Invalid or missing API keyapplication/json403Insufficient permissionsapplication/json404Scenario or accounting account not foundapplication/json429Rate limit exceededapplication/json