StabisoDocs

API reference

Saved reports

Lists and reports a person builds (or asks the assistant for) and keeps: run, shared, pinned to Home and e-mailed on a schedule, each reader seeing what they may.

Operation Summary Scope Idempotency-Key
GET /v1/entities/{entity}/saved-reports List saved reports read
POST /v1/entities/{entity}/saved-reports Save a report read
POST /v1/entities/{entity}/saved-reports/run Run a report read
GET /v1/saved-report-sources List what a report can read read
GET /v1/saved-reports/{report_id} Read a saved report read
PATCH /v1/saved-reports/{report_id} Change a saved report read
DELETE /v1/saved-reports/{report_id} Delete a saved report read
GET /v1/saved-reports/{report_id}/csv Download a saved report read
PUT /v1/saved-reports/{report_id}/pin Pin to Home read
DELETE /v1/saved-reports/{report_id}/pin Unpin from Home read
GET /v1/saved-reports/{report_id}/result Run a saved report read
POST /v1/saved-reports/{report_id}/send E-mail a report now read

GET /v1/entities/{entity}/saved-reports

List saved reports

The company's reports the caller may open: their own and those shared with them, the pinned ones first.

Required scope read (admin implies every scope)
Operation id list_saved_reports_v1_entities__entity__saved_reports_get

Parameters

In Name Type Required Description
path entity string yes Entity code, e.g. CH01 (GET /v1/entities).
query pinned boolean Only those on the caller's Home, in the order pinned. (default false)

Example request

curl "$ERP_URL/v1/entities/CH01/saved-reports" \
  -H "Authorization: Bearer $ERP_KEY"

Responses

Status Meaning Body
200 OK array of SavedReportOut
401 Missing or invalid API key (unauthorized). ErrorEnvelope
403 The caller lacks the required scope (missing_right, with scope), the key belongs to no person where a person is needed (forbidden), or the approval policy denies the action (policy_denied, with action and rule_id). ErrorEnvelope
404 The resource does not exist, or belongs to another organization (not_found). ErrorEnvelope
422 Validation failed: the error envelope (validation_failed). For a malformed body or parameter its message is in sentences ("Line 2: the quantity must be above zero") and fields lists each error with pydantic's loc, type and msg beside its sentence (message) and its parts, to word it in another language: items (name and number from 1: line 2), field (its name as sent) and the rule it breaks with its limit, count and choices (none for a validator's own sentence); FastAPI's own detail list stays beside the envelope. HTTPValidationError

Example response (shape)

[
  {
    "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "entity": "string",
    "name": "string",
    "definition": {
      "filters": [
        {
          "field": "kind",
          "op": "eq",
          "value": "sales_invoice"
        },
        {
          "field": "payment",
          "op": "in",
          "value": [
            "open",
            "overdue"
          ]
        },
        {
          "field": "open_amount",
          "op": "gt",
          "value": "10000"
        },
        {
          "field": "country",
          "op": "eq",
          "value": "DE"
        }
      ],
      "group_by": "sales_person",
      "source": "sales_invoices",
      "sums": [
        "open_amount"
      ]
    },
    "owner": {
      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
      "name": "string"
    },
    "mine": true,
    "sharing": {
      "everyone": false,
      "people": [
        "3fa85f64-5717-4562-b3fc-2c963f66afa6"
      ]
    },
    "schedule": {
      "every": "week",
      "weekday": 0,
      "day": 1,
      "hour": 7,
      "recipients": [
        null
      ]
    },
    "next_send_at": "2026-09-21T09:30:00Z",
    "last_sent_at": "2026-09-21T09:30:00Z",
    "last_send_problem": "string",
    "pinned": true,
    "path": "string",
    "created_at": "2026-09-21T09:30:00Z",
    "updated_at": "2026-09-21T09:30:00Z"
  }
]

POST /v1/entities/{entity}/saved-reports

Save a report

Keep a report: only definition is needed (the name defaults to the source's). Shared with everyone or some people, they open it as themselves. A schedule e-mails it to its owner and people it is shared with. Audited as saved_report.create.

Required scope read (admin implies every scope)
Idempotency-Key not used
Operation id create_saved_report_v1_entities__entity__saved_reports_post

Parameters

In Name Type Required Description
path entity string yes Entity code, e.g. CH01 (GET /v1/entities).

Request body

application/json (required): SavedReportIn

Field Type Required Description
definition ReportDefinition yes What the report lists.
name string or null What the report is called; default: the source's name. (min length 1; max length 120)
sharing ReportSharing or null Default: only the owner.
schedule ReportSchedule or null Default: not sent.
pinned boolean Pin it to the owner's Home at once. (default false)

Example request

curl -X POST "$ERP_URL/v1/entities/CH01/saved-reports" \
  -H "Authorization: Bearer $ERP_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "definition": {
    "filters": [
      {
        "field": "kind",
        "op": "eq",
        "value": "sales_invoice"
      },
      {
        "field": "payment",
        "op": "in",
        "value": [
          "open",
          "overdue"
        ]
      },
      {
        "field": "open_amount",
        "op": "gt",
        "value": "10000"
      },
      {
        "field": "country",
        "op": "eq",
        "value": "DE"
      }
    ],
    "group_by": "sales_person",
    "source": "sales_invoices",
    "sums": [
      "open_amount"
    ]
  },
  "name": "Unpaid invoices in Germany"
}'

Responses

Status Meaning Body
201 Created SavedReportOut
401 Missing or invalid API key (unauthorized). ErrorEnvelope
403 The caller lacks the required scope (missing_right, with scope), the key belongs to no person where a person is needed (forbidden), or the approval policy denies the action (policy_denied, with action and rule_id). ErrorEnvelope
404 The resource does not exist, or belongs to another organization (not_found). ErrorEnvelope
409 The request conflicts with the data: an Idempotency-Key reused with a different request, a closed period, or an integrity rule of the database (conflict, integrity_violation). ErrorEnvelope
422 Validation failed: the error envelope (validation_failed). For a malformed body or parameter its message is in sentences ("Line 2: the quantity must be above zero") and fields lists each error with pydantic's loc, type and msg beside its sentence (message) and its parts, to word it in another language: items (name and number from 1: line 2), field (its name as sent) and the rule it breaks with its limit, count and choices (none for a validator's own sentence); FastAPI's own detail list stays beside the envelope. HTTPValidationError

Example response (shape)

{
  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "entity": "string",
  "name": "string",
  "definition": {
    "filters": [
      {
        "field": "kind",
        "op": "eq",
        "value": "sales_invoice"
      },
      {
        "field": "payment",
        "op": "in",
        "value": [
          "open",
          "overdue"
        ]
      },
      {
        "field": "open_amount",
        "op": "gt",
        "value": "10000"
      },
      {
        "field": "country",
        "op": "eq",
        "value": "DE"
      }
    ],
    "group_by": "sales_person",
    "source": "sales_invoices",
    "sums": [
      "open_amount"
    ]
  },
  "owner": {
    "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "name": "string"
  },
  "mine": true,
  "sharing": {
    "everyone": false,
    "people": [
      "3fa85f64-5717-4562-b3fc-2c963f66afa6"
    ]
  },
  "schedule": {
    "every": "week",
    "weekday": 0,
    "day": 1,
    "hour": 7,
    "recipients": [
      "3fa85f64-5717-4562-b3fc-2c963f66afa6"
    ]
  },
  "next_send_at": "2026-09-21T09:30:00Z",
  "last_sent_at": "2026-09-21T09:30:00Z",
  "last_send_problem": "string",
  "pinned": true,
  "path": "string",
  "created_at": "2026-09-21T09:30:00Z",
  "updated_at": "2026-09-21T09:30:00Z"
}

POST /v1/entities/{entity}/saved-reports/run

Run a report

Run a report without saving it: the rows (or groups, with their counts and sums) the caller may see, the totals of everything found, and for each row where it opens in the app (each group carries the report of its rows, drill). Changes nothing. 422 saved_report_invalid names a field its source does not have; saved_report_day a date that is not one.

Required scope read (admin implies every scope)
Idempotency-Key not used
Operation id run_report_v1_entities__entity__saved_reports_run_post

Parameters

In Name Type Required Description
path entity string yes Entity code, e.g. CH01 (GET /v1/entities).
query language "de" | "en" | "fr" | "it" | "sv" The language of the labels: en (default), de, fr, it, sv. (default "en")

Request body

application/json (required): ReportDefinition

Field Type Required Description
source "bills" | "customers" | "deals" | "journal_lines" | "leads" | "payments" | "products" | "purchase_orders" | "sales_invoices" | "subscriptions" | "vendors" yes The kind of record the report lists (GET /v1/saved-report-sources lists each with its fields).
columns array of string The fields shown, in order; empty: the source's usual ones. (max items 12)
filters array of ReportFilter The conditions a row meets, all of them. (max items 16)
group_by string or null A field to group the rows by: one line per value, with the count and the sums. Amounts in a record's own currency are grouped per currency as well. (max length 40)
sums array of string The amounts or numbers added up for each group and in the totals; empty: the source's main amount. (max items 4)
sort array of ReportSort The order. (max items 3)
limit integer Rows or groups shown, at most 500. (min 1; max 500; default 100)

Example request

curl -X POST "$ERP_URL/v1/entities/CH01/saved-reports/run" \
  -H "Authorization: Bearer $ERP_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "filters": [
    {
      "field": "kind",
      "op": "eq",
      "value": "sales_invoice"
    },
    {
      "field": "payment",
      "op": "in",
      "value": [
        "open",
        "overdue"
      ]
    },
    {
      "field": "open_amount",
      "op": "gt",
      "value": "10000"
    },
    {
      "field": "country",
      "op": "eq",
      "value": "DE"
    }
  ],
  "group_by": "sales_person",
  "source": "sales_invoices",
  "sums": [
    "open_amount"
  ]
}'

Responses

Status Meaning Body
200 OK ReportResult
401 Missing or invalid API key (unauthorized). ErrorEnvelope
403 The caller lacks the required scope (missing_right, with scope), the key belongs to no person where a person is needed (forbidden), or the approval policy denies the action (policy_denied, with action and rule_id). ErrorEnvelope
404 The resource does not exist, or belongs to another organization (not_found). ErrorEnvelope
409 The request conflicts with the data: an Idempotency-Key reused with a different request, a closed period, or an integrity rule of the database (conflict, integrity_violation). ErrorEnvelope
422 Validation failed: the error envelope (validation_failed). For a malformed body or parameter its message is in sentences ("Line 2: the quantity must be above zero") and fields lists each error with pydantic's loc, type and msg beside its sentence (message) and its parts, to word it in another language: items (name and number from 1: line 2), field (its name as sent) and the rule it breaks with its limit, count and choices (none for a validator's own sentence); FastAPI's own detail list stays beside the envelope. HTTPValidationError

Example response (shape)

{
  "entity": "string",
  "source": "bills",
  "title": "string",
  "as_of": "2026-09-21",
  "company_currency": "string",
  "columns": [
    {
      "name": "string",
      "label": "string",
      "type": "string",
      "currency": "string"
    }
  ],
  "rows": [
    {
      "values": {},
      "labels": {},
      "path": "string"
    }
  ],
  "groups": [
    {
      "value": null,
      "label": "string",
      "currency": "string",
      "count": 1,
      "sums": {},
      "drill": {
        "filters": [
          {
            "field": "kind",
            "op": "eq",
            "value": "sales_invoice"
          },
          {
            "field": "payment",
            "op": "in",
            "value": [
              "open",
              "overdue"
            ]
          },
          {
            "field": "open_amount",
            "op": "gt",
            "value": "10000"
          },
          {
            "field": "country",
            "op": "eq",
            "value": "DE"
          }
        ],
        "group_by": "sales_person",
        "source": "sales_invoices",
        "sums": [
          "open_amount"
        ]
      }
    }
  ],
  "group_by": {
    "name": "string",
    "label": "string",
    "type": "string",
    "currency": "string"
  },
  "sums": [
    {
      "name": "string",
      "label": "string",
      "type": "string",
      "currency": "string"
    }
  ],
  "totals": [
    {
      "currency": "string",
      "count": 1,
      "sums": {}
    }
  ],
  "found": 1,
  "truncated": true,
  "definition": {
    "filters": [
      {
        "field": "kind",
        "op": "eq",
        "value": "sales_invoice"
      },
      {
        "field": "payment",
        "op": "in",
        "value": [
          "open",
          "overdue"
        ]
      },
      {
        "field": "open_amount",
        "op": "gt",
        "value": "10000"
      },
      {
        "field": "country",
        "op": "eq",
        "value": "DE"
      }
    ],
    "group_by": "sales_person",
    "source": "sales_invoices",
    "sums": [
      "open_amount"
    ]
  }
}

GET /v1/saved-report-sources

List what a report can read

The kinds of record a report lists (invoices, bills, customers, vendors, deals, leads, payments, purchase orders, subscriptions, journal lines, products), each with its fields: their type, the values of a list, whether a report may group by them, and the usual columns.

Required scope read (admin implies every scope)
Operation id list_sources_v1_saved_report_sources_get

Parameters

In Name Type Required Description
query language "de" | "en" | "fr" | "it" | "sv" The language of the labels: en (default), de, fr, it, sv. (default "en")

Example request

curl "$ERP_URL/v1/saved-report-sources" \
  -H "Authorization: Bearer $ERP_KEY"

Responses

Status Meaning Body
200 OK array of ReportSourceOut
401 Missing or invalid API key (unauthorized). ErrorEnvelope
403 The caller lacks the required scope (missing_right, with scope), the key belongs to no person where a person is needed (forbidden), or the approval policy denies the action (policy_denied, with action and rule_id). ErrorEnvelope
422 Validation failed: the error envelope (validation_failed). For a malformed body or parameter its message is in sentences ("Line 2: the quantity must be above zero") and fields lists each error with pydantic's loc, type and msg beside its sentence (message) and its parts, to word it in another language: items (name and number from 1: line 2), field (its name as sent) and the rule it breaks with its limit, count and choices (none for a validator's own sentence); FastAPI's own detail list stays beside the envelope. HTTPValidationError

Example response (shape)

[
  {
    "name": "bills",
    "label": "string",
    "fields": [
      {
        "name": "string",
        "label": "string",
        "type": "bool",
        "values": [
          null
        ],
        "value_labels": {},
        "group": true,
        "default": true,
        "currency": null
      }
    ],
    "sum": "string"
  }
]

GET /v1/saved-reports/{report_id}

Read a saved report

A report of the caller's or one shared with them (404 saved_report_not_found for any other).

Required scope read (admin implies every scope)
Operation id get_saved_report_v1_saved_reports__report_id__get

Parameters

In Name Type Required Description
path report_id string (uuid) yes Saved report id (GET /v1/entities/{entity}/saved-reports).

Example request

curl "$ERP_URL/v1/saved-reports/3fa85f64-5717-4562-b3fc-2c963f66afa6" \
  -H "Authorization: Bearer $ERP_KEY"

Responses

Status Meaning Body
200 OK SavedReportOut
401 Missing or invalid API key (unauthorized). ErrorEnvelope
403 The caller lacks the required scope (missing_right, with scope), the key belongs to no person where a person is needed (forbidden), or the approval policy denies the action (policy_denied, with action and rule_id). ErrorEnvelope
404 The resource does not exist, or belongs to another organization (not_found). ErrorEnvelope
422 Validation failed: the error envelope (validation_failed). For a malformed body or parameter its message is in sentences ("Line 2: the quantity must be above zero") and fields lists each error with pydantic's loc, type and msg beside its sentence (message) and its parts, to word it in another language: items (name and number from 1: line 2), field (its name as sent) and the rule it breaks with its limit, count and choices (none for a validator's own sentence); FastAPI's own detail list stays beside the envelope. HTTPValidationError

Example response (shape)

{
  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "entity": "string",
  "name": "string",
  "definition": {
    "filters": [
      {
        "field": "kind",
        "op": "eq",
        "value": "sales_invoice"
      },
      {
        "field": "payment",
        "op": "in",
        "value": [
          "open",
          "overdue"
        ]
      },
      {
        "field": "open_amount",
        "op": "gt",
        "value": "10000"
      },
      {
        "field": "country",
        "op": "eq",
        "value": "DE"
      }
    ],
    "group_by": "sales_person",
    "source": "sales_invoices",
    "sums": [
      "open_amount"
    ]
  },
  "owner": {
    "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "name": "string"
  },
  "mine": true,
  "sharing": {
    "everyone": false,
    "people": [
      "3fa85f64-5717-4562-b3fc-2c963f66afa6"
    ]
  },
  "schedule": {
    "every": "week",
    "weekday": 0,
    "day": 1,
    "hour": 7,
    "recipients": [
      "3fa85f64-5717-4562-b3fc-2c963f66afa6"
    ]
  },
  "next_send_at": "2026-09-21T09:30:00Z",
  "last_sent_at": "2026-09-21T09:30:00Z",
  "last_send_problem": "string",
  "pinned": true,
  "path": "string",
  "created_at": "2026-09-21T09:30:00Z",
  "updated_at": "2026-09-21T09:30:00Z"
}

PATCH /v1/saved-reports/{report_id}

Change a saved report

Its name, definition, sharing or schedule; only the fields sent change (unschedule stops the e-mails). Only its owner (403 saved_report_not_yours). A person it is no longer shared with loses it from their Home and its e-mails. Audited as saved_report.update.

Required scope read (admin implies every scope)
Idempotency-Key not used
Operation id update_saved_report_v1_saved_reports__report_id__patch

Parameters

In Name Type Required Description
path report_id string (uuid) yes Saved report id (GET /v1/entities/{entity}/saved-reports).

Request body

application/json (required): SavedReportUpdate

Field Type Required Description
name string or null A new name; null: kept. (min length 1; max length 120)
definition ReportDefinition or null What the report lists from now on; null: kept.
sharing ReportSharing or null Who may open it from now on; null: kept.
schedule ReportSchedule or null A schedule replaces the one there; see unschedule.
unschedule boolean Stop sending it. (default false)

Example request

curl -X PATCH "$ERP_URL/v1/saved-reports/3fa85f64-5717-4562-b3fc-2c963f66afa6" \
  -H "Authorization: Bearer $ERP_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "Unpaid in Germany"
}'

Responses

Status Meaning Body
200 OK SavedReportOut
401 Missing or invalid API key (unauthorized). ErrorEnvelope
403 The caller lacks the required scope (missing_right, with scope), the key belongs to no person where a person is needed (forbidden), or the approval policy denies the action (policy_denied, with action and rule_id). ErrorEnvelope
404 The resource does not exist, or belongs to another organization (not_found). ErrorEnvelope
409 The request conflicts with the data: an Idempotency-Key reused with a different request, a closed period, or an integrity rule of the database (conflict, integrity_violation). ErrorEnvelope
422 Validation failed: the error envelope (validation_failed). For a malformed body or parameter its message is in sentences ("Line 2: the quantity must be above zero") and fields lists each error with pydantic's loc, type and msg beside its sentence (message) and its parts, to word it in another language: items (name and number from 1: line 2), field (its name as sent) and the rule it breaks with its limit, count and choices (none for a validator's own sentence); FastAPI's own detail list stays beside the envelope. HTTPValidationError

Example response (shape)

{
  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "entity": "string",
  "name": "string",
  "definition": {
    "filters": [
      {
        "field": "kind",
        "op": "eq",
        "value": "sales_invoice"
      },
      {
        "field": "payment",
        "op": "in",
        "value": [
          "open",
          "overdue"
        ]
      },
      {
        "field": "open_amount",
        "op": "gt",
        "value": "10000"
      },
      {
        "field": "country",
        "op": "eq",
        "value": "DE"
      }
    ],
    "group_by": "sales_person",
    "source": "sales_invoices",
    "sums": [
      "open_amount"
    ]
  },
  "owner": {
    "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "name": "string"
  },
  "mine": true,
  "sharing": {
    "everyone": false,
    "people": [
      "3fa85f64-5717-4562-b3fc-2c963f66afa6"
    ]
  },
  "schedule": {
    "every": "week",
    "weekday": 0,
    "day": 1,
    "hour": 7,
    "recipients": [
      "3fa85f64-5717-4562-b3fc-2c963f66afa6"
    ]
  },
  "next_send_at": "2026-09-21T09:30:00Z",
  "last_sent_at": "2026-09-21T09:30:00Z",
  "last_send_problem": "string",
  "pinned": true,
  "path": "string",
  "created_at": "2026-09-21T09:30:00Z",
  "updated_at": "2026-09-21T09:30:00Z"
}

DELETE /v1/saved-reports/{report_id}

Delete a saved report

Only its owner; it leaves every Home it was pinned to. Audited as saved_report.delete.

Required scope read (admin implies every scope)
Idempotency-Key not used
Operation id delete_saved_report_v1_saved_reports__report_id__delete

Parameters

In Name Type Required Description
path report_id string (uuid) yes Saved report id (GET /v1/entities/{entity}/saved-reports).

Example request

curl -X DELETE "$ERP_URL/v1/saved-reports/3fa85f64-5717-4562-b3fc-2c963f66afa6" \
  -H "Authorization: Bearer $ERP_KEY"

Responses

Status Meaning Body
204 No content
401 Missing or invalid API key (unauthorized). ErrorEnvelope
403 The caller lacks the required scope (missing_right, with scope), the key belongs to no person where a person is needed (forbidden), or the approval policy denies the action (policy_denied, with action and rule_id). ErrorEnvelope
404 The resource does not exist, or belongs to another organization (not_found). ErrorEnvelope
409 The request conflicts with the data: an Idempotency-Key reused with a different request, a closed period, or an integrity rule of the database (conflict, integrity_violation). ErrorEnvelope
422 Validation failed: the error envelope (validation_failed). For a malformed body or parameter its message is in sentences ("Line 2: the quantity must be above zero") and fields lists each error with pydantic's loc, type and msg beside its sentence (message) and its parts, to word it in another language: items (name and number from 1: line 2), field (its name as sent) and the rule it breaks with its limit, count and choices (none for a validator's own sentence); FastAPI's own detail list stays beside the envelope. HTTPValidationError

GET /v1/saved-reports/{report_id}/csv

Download a saved report

Every row (or group) shown, as a CSV file a spreadsheet opens.

Required scope read (admin implies every scope)
Operation id download_saved_report_v1_saved_reports__report_id__csv_get

Parameters

In Name Type Required Description
path report_id string (uuid) yes Saved report id (GET /v1/entities/{entity}/saved-reports).
query language "de" | "en" | "fr" | "it" | "sv" The language of the labels: en (default), de, fr, it, sv. (default "en")

Example request

curl "$ERP_URL/v1/saved-reports/3fa85f64-5717-4562-b3fc-2c963f66afa6/csv" \
  -H "Authorization: Bearer $ERP_KEY"

Responses

Status Meaning Body
200 The rows as CSV. text/csv
401 Missing or invalid API key (unauthorized). ErrorEnvelope
403 The caller lacks the required scope (missing_right, with scope), the key belongs to no person where a person is needed (forbidden), or the approval policy denies the action (policy_denied, with action and rule_id). ErrorEnvelope
404 The resource does not exist, or belongs to another organization (not_found). ErrorEnvelope
422 Validation failed: the error envelope (validation_failed). For a malformed body or parameter its message is in sentences ("Line 2: the quantity must be above zero") and fields lists each error with pydantic's loc, type and msg beside its sentence (message) and its parts, to word it in another language: items (name and number from 1: line 2), field (its name as sent) and the rule it breaks with its limit, count and choices (none for a validator's own sentence); FastAPI's own detail list stays beside the envelope. HTTPValidationError

PUT /v1/saved-reports/{report_id}/pin

Pin to Home

Show the report on the caller's Home; pinning it again changes nothing.

Required scope read (admin implies every scope)
Idempotency-Key not used
Operation id pin_saved_report_v1_saved_reports__report_id__pin_put

Parameters

In Name Type Required Description
path report_id string (uuid) yes Saved report id (GET /v1/entities/{entity}/saved-reports).

Example request

curl -X PUT "$ERP_URL/v1/saved-reports/3fa85f64-5717-4562-b3fc-2c963f66afa6/pin" \
  -H "Authorization: Bearer $ERP_KEY"

Responses

Status Meaning Body
200 OK SavedReportOut
401 Missing or invalid API key (unauthorized). ErrorEnvelope
403 The caller lacks the required scope (missing_right, with scope), the key belongs to no person where a person is needed (forbidden), or the approval policy denies the action (policy_denied, with action and rule_id). ErrorEnvelope
404 The resource does not exist, or belongs to another organization (not_found). ErrorEnvelope
409 The request conflicts with the data: an Idempotency-Key reused with a different request, a closed period, or an integrity rule of the database (conflict, integrity_violation). ErrorEnvelope
422 Validation failed: the error envelope (validation_failed). For a malformed body or parameter its message is in sentences ("Line 2: the quantity must be above zero") and fields lists each error with pydantic's loc, type and msg beside its sentence (message) and its parts, to word it in another language: items (name and number from 1: line 2), field (its name as sent) and the rule it breaks with its limit, count and choices (none for a validator's own sentence); FastAPI's own detail list stays beside the envelope. HTTPValidationError

Example response (shape)

{
  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "entity": "string",
  "name": "string",
  "definition": {
    "filters": [
      {
        "field": "kind",
        "op": "eq",
        "value": "sales_invoice"
      },
      {
        "field": "payment",
        "op": "in",
        "value": [
          "open",
          "overdue"
        ]
      },
      {
        "field": "open_amount",
        "op": "gt",
        "value": "10000"
      },
      {
        "field": "country",
        "op": "eq",
        "value": "DE"
      }
    ],
    "group_by": "sales_person",
    "source": "sales_invoices",
    "sums": [
      "open_amount"
    ]
  },
  "owner": {
    "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "name": "string"
  },
  "mine": true,
  "sharing": {
    "everyone": false,
    "people": [
      "3fa85f64-5717-4562-b3fc-2c963f66afa6"
    ]
  },
  "schedule": {
    "every": "week",
    "weekday": 0,
    "day": 1,
    "hour": 7,
    "recipients": [
      "3fa85f64-5717-4562-b3fc-2c963f66afa6"
    ]
  },
  "next_send_at": "2026-09-21T09:30:00Z",
  "last_sent_at": "2026-09-21T09:30:00Z",
  "last_send_problem": "string",
  "pinned": true,
  "path": "string",
  "created_at": "2026-09-21T09:30:00Z",
  "updated_at": "2026-09-21T09:30:00Z"
}

DELETE /v1/saved-reports/{report_id}/pin

Unpin from Home

Take the report off the caller's Home.

Required scope read (admin implies every scope)
Idempotency-Key not used
Operation id unpin_saved_report_v1_saved_reports__report_id__pin_delete

Parameters

In Name Type Required Description
path report_id string (uuid) yes Saved report id (GET /v1/entities/{entity}/saved-reports).

Example request

curl -X DELETE "$ERP_URL/v1/saved-reports/3fa85f64-5717-4562-b3fc-2c963f66afa6/pin" \
  -H "Authorization: Bearer $ERP_KEY"

Responses

Status Meaning Body
200 OK SavedReportOut
401 Missing or invalid API key (unauthorized). ErrorEnvelope
403 The caller lacks the required scope (missing_right, with scope), the key belongs to no person where a person is needed (forbidden), or the approval policy denies the action (policy_denied, with action and rule_id). ErrorEnvelope
404 The resource does not exist, or belongs to another organization (not_found). ErrorEnvelope
409 The request conflicts with the data: an Idempotency-Key reused with a different request, a closed period, or an integrity rule of the database (conflict, integrity_violation). ErrorEnvelope
422 Validation failed: the error envelope (validation_failed). For a malformed body or parameter its message is in sentences ("Line 2: the quantity must be above zero") and fields lists each error with pydantic's loc, type and msg beside its sentence (message) and its parts, to word it in another language: items (name and number from 1: line 2), field (its name as sent) and the rule it breaks with its limit, count and choices (none for a validator's own sentence); FastAPI's own detail list stays beside the envelope. HTTPValidationError

Example response (shape)

{
  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "entity": "string",
  "name": "string",
  "definition": {
    "filters": [
      {
        "field": "kind",
        "op": "eq",
        "value": "sales_invoice"
      },
      {
        "field": "payment",
        "op": "in",
        "value": [
          "open",
          "overdue"
        ]
      },
      {
        "field": "open_amount",
        "op": "gt",
        "value": "10000"
      },
      {
        "field": "country",
        "op": "eq",
        "value": "DE"
      }
    ],
    "group_by": "sales_person",
    "source": "sales_invoices",
    "sums": [
      "open_amount"
    ]
  },
  "owner": {
    "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "name": "string"
  },
  "mine": true,
  "sharing": {
    "everyone": false,
    "people": [
      "3fa85f64-5717-4562-b3fc-2c963f66afa6"
    ]
  },
  "schedule": {
    "every": "week",
    "weekday": 0,
    "day": 1,
    "hour": 7,
    "recipients": [
      "3fa85f64-5717-4562-b3fc-2c963f66afa6"
    ]
  },
  "next_send_at": "2026-09-21T09:30:00Z",
  "last_sent_at": "2026-09-21T09:30:00Z",
  "last_send_problem": "string",
  "pinned": true,
  "path": "string",
  "created_at": "2026-09-21T09:30:00Z",
  "updated_at": "2026-09-21T09:30:00Z"
}

GET /v1/saved-reports/{report_id}/result

Run a saved report

The report as of today, as the caller sees it.

Required scope read (admin implies every scope)
Operation id run_saved_report_v1_saved_reports__report_id__result_get

Parameters

In Name Type Required Description
path report_id string (uuid) yes Saved report id (GET /v1/entities/{entity}/saved-reports).
query language "de" | "en" | "fr" | "it" | "sv" The language of the labels: en (default), de, fr, it, sv. (default "en")

Example request

curl "$ERP_URL/v1/saved-reports/3fa85f64-5717-4562-b3fc-2c963f66afa6/result" \
  -H "Authorization: Bearer $ERP_KEY"

Responses

Status Meaning Body
200 OK ReportResult
401 Missing or invalid API key (unauthorized). ErrorEnvelope
403 The caller lacks the required scope (missing_right, with scope), the key belongs to no person where a person is needed (forbidden), or the approval policy denies the action (policy_denied, with action and rule_id). ErrorEnvelope
404 The resource does not exist, or belongs to another organization (not_found). ErrorEnvelope
422 Validation failed: the error envelope (validation_failed). For a malformed body or parameter its message is in sentences ("Line 2: the quantity must be above zero") and fields lists each error with pydantic's loc, type and msg beside its sentence (message) and its parts, to word it in another language: items (name and number from 1: line 2), field (its name as sent) and the rule it breaks with its limit, count and choices (none for a validator's own sentence); FastAPI's own detail list stays beside the envelope. HTTPValidationError

Example response (shape)

{
  "entity": "string",
  "source": "bills",
  "title": "string",
  "as_of": "2026-09-21",
  "company_currency": "string",
  "columns": [
    {
      "name": "string",
      "label": "string",
      "type": "string",
      "currency": "string"
    }
  ],
  "rows": [
    {
      "values": {},
      "labels": {},
      "path": "string"
    }
  ],
  "groups": [
    {
      "value": null,
      "label": "string",
      "currency": "string",
      "count": 1,
      "sums": {},
      "drill": {
        "filters": [
          {
            "field": "kind",
            "op": "eq",
            "value": "sales_invoice"
          },
          {
            "field": "payment",
            "op": "in",
            "value": [
              "open",
              "overdue"
            ]
          },
          {
            "field": "open_amount",
            "op": "gt",
            "value": "10000"
          },
          {
            "field": "country",
            "op": "eq",
            "value": "DE"
          }
        ],
        "group_by": "sales_person",
        "source": "sales_invoices",
        "sums": [
          "open_amount"
        ]
      }
    }
  ],
  "group_by": {
    "name": "string",
    "label": "string",
    "type": "string",
    "currency": "string"
  },
  "sums": [
    {
      "name": "string",
      "label": "string",
      "type": "string",
      "currency": "string"
    }
  ],
  "totals": [
    {
      "currency": "string",
      "count": 1,
      "sums": {}
    }
  ],
  "found": 1,
  "truncated": true,
  "definition": {
    "filters": [
      {
        "field": "kind",
        "op": "eq",
        "value": "sales_invoice"
      },
      {
        "field": "payment",
        "op": "in",
        "value": [
          "open",
          "overdue"
        ]
      },
      {
        "field": "open_amount",
        "op": "gt",
        "value": "10000"
      },
      {
        "field": "country",
        "op": "eq",
        "value": "DE"
      }
    ],
    "group_by": "sales_person",
    "source": "sales_invoices",
    "sums": [
      "open_amount"
    ]
  }
}

POST /v1/saved-reports/{report_id}/send

E-mail a report now

E-mail the report now to the recipients of its schedule (its owner alone without one), each with what they see; the schedule stays as it is. Only its owner, at most once in five minutes (409 saved_report_sent_recently).

Required scope read (admin implies every scope)
Idempotency-Key not used
Operation id send_saved_report_v1_saved_reports__report_id__send_post

Parameters

In Name Type Required Description
path report_id string (uuid) yes Saved report id (GET /v1/entities/{entity}/saved-reports).

Example request

curl -X POST "$ERP_URL/v1/saved-reports/3fa85f64-5717-4562-b3fc-2c963f66afa6/send" \
  -H "Authorization: Bearer $ERP_KEY"

Responses

Status Meaning Body
200 OK ReportSendOut
401 Missing or invalid API key (unauthorized). ErrorEnvelope
403 The caller lacks the required scope (missing_right, with scope), the key belongs to no person where a person is needed (forbidden), or the approval policy denies the action (policy_denied, with action and rule_id). ErrorEnvelope
404 The resource does not exist, or belongs to another organization (not_found). ErrorEnvelope
409 The request conflicts with the data: an Idempotency-Key reused with a different request, a closed period, or an integrity rule of the database (conflict, integrity_violation). ErrorEnvelope
422 Validation failed: the error envelope (validation_failed). For a malformed body or parameter its message is in sentences ("Line 2: the quantity must be above zero") and fields lists each error with pydantic's loc, type and msg beside its sentence (message) and its parts, to word it in another language: items (name and number from 1: line 2), field (its name as sent) and the rule it breaks with its limit, count and choices (none for a validator's own sentence); FastAPI's own detail list stays beside the envelope. HTTPValidationError
429 A per-organization limit was reached, e.g. messages sent per hour (rate_limited, with retry_after_seconds). ErrorEnvelope

Example response (shape)

{
  "sent": 1,
  "skipped": 1,
  "problem": "string"
}

Schemas

ReportColumn

Field Type Required Description
name string yes The field, as in the definition.
label string yes Its heading, in the language asked for.
type string yes What it holds, as a source's field says (money, date …).
currency string or null yes Of an amount: the field of its currency, or null for the company's.

ReportDefinition

Field Type Required Description
source "bills" | "customers" | "deals" | "journal_lines" | "leads" | "payments" | "products" | "purchase_orders" | "sales_invoices" | "subscriptions" | "vendors" yes The kind of record the report lists (GET /v1/saved-report-sources lists each with its fields).
columns array of string The fields shown, in order; empty: the source's usual ones. (max items 12)
filters array of ReportFilter The conditions a row meets, all of them. (max items 16)
group_by string or null A field to group the rows by: one line per value, with the count and the sums. Amounts in a record's own currency are grouped per currency as well. (max length 40)
sums array of string The amounts or numbers added up for each group and in the totals; empty: the source's main amount. (max items 4)
sort array of ReportSort The order. (max items 3)
limit integer Rows or groups shown, at most 500. (min 1; max 500; default 100)

ReportFilter

Field Type Required Description
field string yes A field of the source, e.g. open_amount. (max length 40)
op "between" | "contains" | "empty" | "eq" | "gt" | "gte" | "in" | "lt" | "lte" | "ne" | "not_in" | "set" eq, ne, gt, gte, lt, lte, in and not_in (a list), contains (text), between (a list of two, both included), empty or set (no value). (default "eq")
value any What the field is compared with: a text, a number or amount as a string, true/false, a list for in, not_in and between. A date is 2026-10-01 or one counted from the company's today: today, today-30, today+7, start_of_week, start_of_month, end_of_month, start_of_quarter, end_of_quarter, start_of_year, end_of_year, start_of_last_month, end_of_last_month, start_of_last_quarter, end_of_last_quarter, start_of_last_year, end_of_last_year. A person is me (who reads the report), a name, an e-mail or an id.

ReportGroup

Field Type Required Description
value any yes The value grouped by; null for the rows without one.
label string yes How the value reads.
currency string or null yes The currency of the group's amounts, if any.
count integer yes Rows in the group.
sums map of string yes The sum of each field added up, by its name.
drill ReportDefinition yes The report of the group's rows: the same report narrowed to the value, not grouped.

ReportOwner

Field Type Required Description
id string (uuid) yes The person's user id.
name string yes The person's name, else their e-mail.

ReportResult

Field Type Required Description
entity string yes The company's code.
source "bills" | "customers" | "deals" | "journal_lines" | "leads" | "payments" | "products" | "purchase_orders" | "sales_invoices" | "subscriptions" | "vendors" yes What the report lists.
title string yes The source's name in the language asked for.
as_of string (date) yes The company's today the report was run on.
company_currency string yes The currency the company keeps its books in.
columns array of ReportColumn yes The columns of the rows, in order.
rows array of ReportRow yes The rows, when the report is not grouped.
groups array of ReportGroup yes The groups, when it is.
group_by ReportColumn or null yes The field grouped by; null: not grouped.
sums array of ReportColumn yes The fields the groups and totals add up.
totals array of ReportTotal yes Of every row found, per currency.
found integer yes Rows found in all (or groups, when grouped).
truncated boolean yes More were found than limit shows.
definition ReportDefinition yes The report as it was run, completed.

ReportRow

Field Type Required Description
values object yes The value of each column (amounts and numbers as strings, dates as ISO days); a list's value as stored, its words in labels.
labels map of string yes The words of the list values of the row.
path string or null yes Where the row opens in the app, e.g. /documents/….

ReportSchedule

Field Type Required Description
every "day" | "month" | "week" How often it is sent: each day, week or month. (default "week")
weekday integer For week: 0 Monday (the default) to 6 Sunday. (min 0; max 6; default 0)
day integer For month: the day, 1 to 28. (min 1; max 28; default 1)
hour integer The hour in the company's time zone (default 7). (min 0; max 23; default 7)
recipients array of string (uuid) Who gets it (user ids): the owner and the people it is shared with; empty: the owner. (max items 50)

ReportSendOut

Field Type Required Description
sent integer yes E-mails sent.
skipped integer yes Recipients not sent to (no mail server, a test copy).
problem string or null yes Why nothing was sent, if so.

ReportSharing

Field Type Required Description
everyone boolean Everyone in the organization may open the report. (default false)
people array of string (uuid) People of the organization the report is shared with (user ids). (max items 50)

ReportSort

Field Type Required Description
by string yes A field; in a grouped report also count or one of its sums. (max length 40)
descending boolean Largest or latest first. (default false)

ReportSourceField

Field Type Required Description
name string yes The field's name in a definition, e.g. open_amount.
label string yes What the field is, in the language asked for.
type "bool" | "country" | "date" | "enum" | "money" | "number" | "person" | "text" yes What it holds: money an amount, enum one of values, person someone of the organization (me in a filter), country an ISO code.
values array of string yes Of a list (enum): its values.
value_labels map of string yes The words of each value.
group boolean yes A report may group by it.
default boolean yes Shown when a report names no columns.
currency string or null yes Of an amount in the record's own currency: the field that holds it; null: the company's currency.

ReportSourceOut

Field Type Required Description
name "bills" | "customers" | "deals" | "journal_lines" | "leads" | "payments" | "products" | "purchase_orders" | "sales_invoices" | "subscriptions" | "vendors" yes The source's name in a definition.
label string yes What it lists, in the language asked for.
fields array of ReportSourceField yes What a report of it may show and filter.
sum string or null yes The amount a grouped report adds up by default.

ReportTotal

Field Type Required Description
currency string or null yes Of the amounts in the records' own currency.
count integer yes Rows found in this currency (or in all).
sums map of string yes The sum of each field added up, by its name.

SavedReportIn

Field Type Required Description
definition ReportDefinition yes What the report lists.
name string or null What the report is called; default: the source's name. (min length 1; max length 120)
sharing ReportSharing or null Default: only the owner.
schedule ReportSchedule or null Default: not sent.
pinned boolean Pin it to the owner's Home at once. (default false)

SavedReportOut

Field Type Required Description
id string (uuid) yes The report's id.
entity string yes The company's code.
name string yes What the report is called.
definition ReportDefinition yes What the report lists.
owner ReportOwner yes Who saved it: only they change it.
mine boolean yes The person asking owns it (and may change it).
sharing ReportSharing yes Who else may open it.
schedule ReportSchedule or null yes When it is e-mailed; null: never.
next_send_at string (date-time) or null yes When it is e-mailed next.
last_sent_at string (date-time) or null yes When it was last e-mailed.
last_send_problem string or null yes Why the last e-mail was not sent, if so.
pinned boolean yes On the Home of the person asking.
path string yes Where it opens in the app.
created_at string (date-time) yes When it was saved.
updated_at string (date-time) or null yes When it was last changed.

SavedReportUpdate

Field Type Required Description
name string or null A new name; null: kept. (min length 1; max length 120)
definition ReportDefinition or null What the report lists from now on; null: kept.
sharing ReportSharing or null Who may open it from now on; null: kept.
schedule ReportSchedule or null A schedule replaces the one there; see unschedule.
unschedule boolean Stop sending it. (default false)
Stabiso, the Enterprise System of Record · generated from the code and its guides · release 6f03a5e846b3