# get_agi_report

## What it answers

Read the planned AGI report by month for one Projects grid and its companion Payroll and Expenses grids: planned AGI, AGI capacity, overall expenses, planned delivery expenses and the derived profit and margins, plus a summary over the whole range. Figures are planned from the grids, not actuals from time entries (get_abr_trend and the utilization tools use actuals). Required range.from and range.to are inclusive YYYY-MM months, at most 60 months. Pending projects are excluded unless includePendingProjects is true. Optional scenarioId (from list_scenarios) applies that saved scenario's Included payroll rows exactly as the report page does, needs Model Calculator access as well, and takes the scenario's stored Include pending setting when includePendingProjects is omitted; the scenario's model-input overrides do not change this report (an overrides-not-applied caveat says so). Requires the current connection owner to have view access to the Projects grid on this account; choose projectGridId when PROJECT_GRID_REQUIRED lists several. Every margin is a ratio of summed parts. No per-person compensation is returned. Sheet-backed input grids carry an INPUTS_NOT_VERIFIED caveat. Read definitions and caveats before interpreting figures. Read parakeeto://methodology for shared response conventions and INVALID_ARGUMENT guidance.

Read-only.

## Arguments

| Argument | Type | Required | Default | Allowed values |
| --- | --- | --- | --- | --- |
| `account` | string (uuid) | no | — | — |
| `includeDefinitions` | boolean | no | `true` | — |
| `projectGridId` | string (uuid) | no | — | — |
| `range` | object | yes | — | — |
| `range.from` | string | yes | — | pattern `^\d{4}-(?:0[1-9]\|1[0-2])$` |
| `range.to` | string | yes | — | pattern `^\d{4}-(?:0[1-9]\|1[0-2])$` |
| `includePendingProjects` | boolean | no | — | — |
| `scenarioId` | string (uuid) | no | — | — |

## Returned fields

The result is an envelope: `ok: true` with `data`, or `ok: false` with `error`. Error codes: `MODEL_CALCULATOR_ACCESS_REQUIRED`, `PAYROLL_GRID_MISSING`, `PAYROLL_GRID_REQUIRED`, `PROJECT_GRID_REQUIRED`, `EXPENSE_GRID_REQUIRED`, `PAYROLL_ENTRY_REFERENCE_STALE`, `ACCOUNT_NOT_FOUND`, `ACCOUNT_CONFIGURATION_MISSING`, `NO_IMPORTED_TIME`, `NOTHING_IMPORTED`, `ACCOUNT_REQUIRED`, `NO_REACHABLE_ACCOUNTS`, `FEATURE_NOT_ENTITLED`, `PERMISSION_DENIED`, `CALCULATION_FAILED`, `INTERNAL_ERROR`, `INVALID_ARGUMENT`.

- `data`: object
  - `data.account`: string (uuid)
  - `data.projectGrid`: object
    - `data.projectGrid.id`: string (uuid)
    - `data.projectGrid.name`: string
  - `data.range`: object
    - `data.range.from`: string (pattern `^\d{4}-(?:0[1-9]|1[0-2])$`)
    - `data.range.to`: string (pattern `^\d{4}-(?:0[1-9]|1[0-2])$`)
  - `data.includesPendingProjects`: boolean
  - `data.gridFreshness`: array of object
    - `data.gridFreshness[].kind`: string (`"payroll"`, `"expense"`, `"project"`)
    - `data.gridFreshness[].gridId`: string (uuid)
    - `data.gridFreshness[].name`: string
    - `data.gridFreshness[].storage`: string (`"sheet"`, `"database"`)
    - `data.gridFreshness[].sheetRefreshedAt`: string (date-time) or null
  - `data.definitions`: map of string to string, optional
    - `data.definitions.*`: string
  - `data.caveats`: array of object
    - `data.caveats[].code`: string
    - `data.caveats[].message`: string
  - `data.months`: array of object
    - `data.months[].month`: string (pattern `^\d{4}-(?:0[1-9]|1[0-2])$`)
    - `data.months[].startDate`: string (pattern `^\d{4}-\d{2}-\d{2}$`)
    - `data.months[].endDate`: string (pattern `^\d{4}-\d{2}-\d{2}$`)
    - `data.months[].agi`: string or null (pattern `^-?\d+(?:\.\d+)?$`)
    - `data.months[].agiCapacity`: string or null (pattern `^-?\d+(?:\.\d+)?$`)
    - `data.months[].expenses`: string or null (pattern `^-?\d+(?:\.\d+)?$`)
    - `data.months[].deliveryExpenses`: string or null (pattern `^-?\d+(?:\.\d+)?$`)
    - `data.months[].profit`: string or null (pattern `^-?\d+(?:\.\d+)?$`)
    - `data.months[].profitAtCapacity`: string or null (pattern `^-?\d+(?:\.\d+)?$`)
    - `data.months[].deliveryMargin`: string or null (pattern `^-?\d+(?:\.\d+)?$`)
    - `data.months[].deliveryMarginAtCapacity`: string or null (pattern `^-?\d+(?:\.\d+)?$`)
    - `data.months[].capacityFilled`: string or null (pattern `^-?\d+(?:\.\d+)?$`)
  - `data.summary`: object
    - `data.summary.agi`: string or null (pattern `^-?\d+(?:\.\d+)?$`)
    - `data.summary.agiCapacity`: string or null (pattern `^-?\d+(?:\.\d+)?$`)
    - `data.summary.expenses`: string or null (pattern `^-?\d+(?:\.\d+)?$`)
    - `data.summary.deliveryExpenses`: string or null (pattern `^-?\d+(?:\.\d+)?$`)
    - `data.summary.profit`: string or null (pattern `^-?\d+(?:\.\d+)?$`)
    - `data.summary.profitAtCapacity`: string or null (pattern `^-?\d+(?:\.\d+)?$`)
    - `data.summary.deliveryMargin`: string or null (pattern `^-?\d+(?:\.\d+)?$`)
    - `data.summary.deliveryMarginAtCapacity`: string or null (pattern `^-?\d+(?:\.\d+)?$`)
    - `data.summary.capacityFilled`: string or null (pattern `^-?\d+(?:\.\d+)?$`)
  - `data.scenario`: object, optional
    - `data.scenario.id`: string (uuid)
    - `data.scenario.name`: string
    - `data.scenario.revision`: string
    - `data.scenario.includePending`: boolean
    - `data.scenario.overrides`: object
      - `data.scenario.overrides.grossCapacity`: string, optional (pattern `^-?\d+(?:\.\d+)?$`)
      - `data.scenario.overrides.modelAbr`: string, optional (pattern `^-?\d+(?:\.\d+)?$`)
      - `data.scenario.overrides.modelUtilization`: string, optional (pattern `^-?\d+(?:\.\d+)?$`)
      - `data.scenario.overrides.deliveryPayrollBudget`: string, optional (pattern `^-?\d+(?:\.\d+)?$`)
      - `data.scenario.overrides.deliveryExpenseBudget`: string, optional (pattern `^-?\d+(?:\.\d+)?$`)
      - `data.scenario.overrides.smPayrollBudget`: string, optional (pattern `^-?\d+(?:\.\d+)?$`)
      - `data.scenario.overrides.smExpenseBudget`: string, optional (pattern `^-?\d+(?:\.\d+)?$`)
      - `data.scenario.overrides.adminPayrollBudget`: string, optional (pattern `^-?\d+(?:\.\d+)?$`)
      - `data.scenario.overrides.adminExpenseBudget`: string, optional (pattern `^-?\d+(?:\.\d+)?$`)
      - `data.scenario.overrides.facilitiesExpenseBudget`: string, optional (pattern `^-?\d+(?:\.\d+)?$`)
    - `data.scenario.missingRows`: string (pattern `^-?\d+(?:\.\d+)?$`)

On failure:

- `error`: object
  - `error.code`: string (`"MODEL_CALCULATOR_ACCESS_REQUIRED"`, `"PAYROLL_GRID_MISSING"`, `"PAYROLL_GRID_REQUIRED"`, `"PROJECT_GRID_REQUIRED"`, `"EXPENSE_GRID_REQUIRED"`, `"PAYROLL_ENTRY_REFERENCE_STALE"`, `"ACCOUNT_NOT_FOUND"`, `"ACCOUNT_CONFIGURATION_MISSING"`, `"NO_IMPORTED_TIME"`, `"NOTHING_IMPORTED"`, `"ACCOUNT_REQUIRED"`, `"NO_REACHABLE_ACCOUNTS"`, `"FEATURE_NOT_ENTITLED"`, `"PERMISSION_DENIED"`, `"CALCULATION_FAILED"`, `"INTERNAL_ERROR"`, `"INVALID_ARGUMENT"`)
  - `error.argument`: string, optional (`minLength: 1`)
  - `error.message`: string
  - `error.accounts`: array of object, optional
    - `error.accounts[].id`: string (uuid)
    - `error.accounts[].name`: string
  - `error.payrollGrids`: array of object, optional
    - `error.payrollGrids[]`: same shape as `error.accounts[]`
  - `error.projectGrids`: array of object, optional
    - `error.projectGrids[]`: same shape as `error.accounts[]`
  - `error.expenseGrids`: array of object, optional
    - `error.expenseGrids[]`: same shape as `error.accounts[]`
  - `error.context`: object, optional
    - `error.context.account`: object
      - Further fields: see the response.
    - `error.context.imports`: array of object
      - Further fields: see the response.
    - `error.context.hasTimeEntries`: boolean
    - `error.context.reports`: array of object
      - Further fields: see the response.

## Definitions

Returned in `definitions` when `includeDefinitions` is true (the default). It is a map of string to string: each key names a field and each value is its definition text.

## Caveats

Codes are not enumerated in the schema; read each `code` and `message`.

Read every caveat before interpreting a figure. See [methodology](</methodology.md>) on how to communicate caveats and data-quality conditions.

## Example call

```json
{
  "name": "get_agi_report",
  "arguments": {
    "range": {
      "from": "2026-01",
      "to": "2026-03"
    }
  }
}
```

Add `account` with an identifier from `list_accounts`; omit it only when the connection reaches exactly one account.
