Outcomes
The Outcomes endpoints return what the Outcomes page in Harmony shows: how each team is doing for a month or a quarter, what work was finished and how much of it was useful, and what needs attention. An admin's key can also set monthly budgets.
Money is always returned in the minor unit of the organization's currency: pence for gbp, cents for usd. 125000 with currency: "gbp" is £1,250.00.
What a key can see follows the person who created it. An admin's key sees the whole organization; any other key sees the teams its creator belongs to, and only its creator's own money. Fields a key may not see come back as null.
Retrieve outcomes
Returns each team's spend, forecast, budget, useful rate and goals for the period, people's spend, every goal's progress and what blocks it, and a list of what needs attention.
GET /v1/outcomes
Scope: outcomes:read
| Parameter | In | Type | Description |
|---|---|---|---|
period |
query | string, optional | month (default) or quarter. |
month |
query | string, optional | YYYY-MM: the month, or any month in the quarter. Defaults to the current month. |
scope |
query | string, optional | all (default) or mine. mine narrows an admin's key to the teams its creator belongs to. |
::: code-group
curl "https://api.gonimbus.ai/v1/outcomes?period=quarter" \
-H "Authorization: Bearer $HARMONY_API_KEY"
const response = await fetch('https://api.gonimbus.ai/v1/outcomes?period=quarter', {
headers: { Authorization: `Bearer ${process.env.HARMONY_API_KEY}` },
})
const outcomes = await response.json()
for (const team of outcomes.teams) {
console.log(team.name, team.spent, team.budget, team.useful_rate)
}
:::
{
"object": "outcomes",
"period": { "kind": "quarter", "start": "2026-10-01", "end": "2026-12-31", "current": true },
"scope": "all",
"currency": "gbp",
"budgets_allowed": true,
"totals": { "spent": 412000, "forecast": 980000, "budget": 1200000 },
"teams": [
{
"id": "team_gtm",
"name": "Go-to-market",
"spent": 47600,
"forecast": 51000,
"budget": 30000,
"over_budget": true,
"forecast_over_budget": true,
"trend": "up",
"useful_rate": 0.74,
"judged": 127,
"people_count": 6,
"goals": ["goal_pipeline"]
}
],
"people": [
{ "id": "usr_sam", "name": "Sam Okafor", "teams": ["team_gtm"], "spent": 9100, "forecast": 11800, "budget": null, "limit_share": 0.62 }
],
"goals": [
{
"id": "goal_pipeline",
"title": "A clean pipeline every Monday",
"team": "team_gtm",
"status": "active",
"metric": { "label": "Weeks with a clean pipeline", "unit": null, "direction": "increase" },
"target": 12,
"progress": 0.17,
"on_track": false,
"latest": { "day": "2026-10-26", "value": 2, "source": "connector" },
"blocked_by": [],
"blocking": []
}
],
"attention": [
{
"kind": "team_over_budget",
"severity": "critical",
"title": "Go-to-market is over its budget",
"detail": "£476 of £300 this month.",
"target": { "kind": "team", "id": "team_gtm" },
"team": "team_gtm"
}
],
"suggestions": []
}
| Field | Description |
|---|---|
period |
The period returned: kind, start and end dates, and whether it is the current one. |
currency |
gbp or usd, lowercase. All money fields use its minor unit. |
budgets_allowed |
Whether the organization's plan includes money budgets. |
totals |
The organization's spend, forecast and budget. Admins' keys only; null otherwise. |
teams[] |
Per team: spent, forecast (projected spend by the end of the period), budget (null when none is set), over_budget, forecast_over_budget, trend (up, flat, down or null), useful_rate (accepted work over judged work, null when too little was judged or value isn't visible to the key), judged, people_count and the ids of its goals. |
people[] |
Per person: their teams, spent, forecast, budget, and limit_share (the share of their usage limit used, from 0; 1 is the whole limit). Money is null where the key may not see it. |
goals[] |
Every goal's progress (0–1 from baseline to target), on_track, latest reading, and the goals it is blocked_by and blocking. |
attention[] |
What needs a look, most severe first. kind is one of team_over_budget, team_near_budget, loop_failing, key_refused, person_near_limit, goal_off_track, goal_suggested or install_waiting; severity is critical, warning or info. |
suggestions[] |
Goals Harmony suggested that are waiting for an admin, with why. Admins' keys only. |
Retrieve value
Returns the work finished in the period, grouped one way, with how much of it people judged and accepted and what it cost.
GET /v1/value
Scope: outcomes:read
| Parameter | In | Type | Description |
|---|---|---|---|
by |
query | string | team, person or loop. |
period |
query | string, optional | month (default) or quarter. |
month |
query | string, optional | YYYY-MM. Defaults to the current month. |
curl "https://api.gonimbus.ai/v1/value?by=loop" \
-H "Authorization: Bearer $HARMONY_API_KEY"
{
"object": "value",
"by": "loop",
"currency": "gbp",
"available": true,
"data": [
{ "id": "loop_pipeline_hygiene", "name": "Pipeline hygiene", "outputs": 4, "judged": 4, "accepted": 3, "useful_rate": 0.75, "cost": 168 }
]
}
available is false when value isn't visible to the key, for example when the organization's plan doesn't show value; data is then empty. useful_rate is accepted over judged, or null when nothing was judged.
Set a budget
Sets the monthly budget for a team or a person. Send monthly_amount: null to clear it. Needs an admin's key and a plan with money budgets; otherwise the request fails with 403.
POST /v1/budgets
Scope: outcomes:write
| Parameter | In | Type | Description |
|---|---|---|---|
scope |
body | string | team or person. |
id |
body | string | The team id, or the person's user id. |
monthly_amount |
body | integer or null | Per month, in the currency's minor unit. null clears the budget. |
currency |
body | string, optional | gbp or usd. Defaults to the organization's currency. |
curl https://api.gonimbus.ai/v1/budgets \
-H "Authorization: Bearer $HARMONY_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "scope": "team", "id": "team_gtm", "monthly_amount": 30000 }'
{ "object": "budget", "scope": "team", "id": "team_gtm", "monthly_amount": 30000, "currency": "gbp" }
Errors
| Status | Code | When |
|---|---|---|
400 |
parameter_invalid |
A parameter has the wrong value, such as period=year or a malformed month. |
403 |
insufficient_scope |
The key doesn't hold the scope, or a budget was set with a key that isn't an admin's or on a plan without money budgets. |
404 |
resource_missing |
No team or person with that id. |
FAQs
Why are some money fields null? The key's creator may not see that money: a member sees their own spend, not their colleagues'. Use an admin's key for the whole organization.
Does reading outcomes cost anything? No. Requests to these endpoints aren't metered.
Where do these numbers come from in the app? The Outcomes and Spend pages. See Outcomes and goals.