---
title: "List the reports of the account"
method: POST
path: "/reports/list"
tags: ["Reports"]
---

# List the reports of the account

`POST /reports/list`

## Request

- Base URL: `https://api.reportingninja.com/v1`
- URL: `https://api.reportingninja.com/v1/reports/list`
- Auth: HTTP bearer

Returns every report of the account, the ones built on one of its templates included, ordered by title. Each row carries the key the other endpoints address it with, the version its structure is at and the report level bindings it reads from. The account's own templates are a different list and are answered by /v1/templates/list; the system catalog is a third one and is answered by /v1/catalog/list.

## Request body

- ReportsListRequest: No parameters.

## Response `200`

The call succeeded. This endpoint reports its errors with a real HTTP status, so a 200 always carries status=ok.

- ReportsListResponse
  - `status` 'ok', required
  - `data` ReportsListData, required: Every report of the account, ordered by title.
    - `reports` ReportHeader[], required
      - `report_key` string, required: The key that addresses this report in every other endpoint.
      - `name` string, nullable, required: Title of the report: the name the cover paints, and the one every write takes as `name`. At most 60 characters.
      - `internal_name` string, nullable, required: The OTHER name of the report: the one the list of the application shows. A report has two and both are writable. At most 100 characters.
      - `subtitle` string, nullable, required: The line under the title of the report, as /v1/reports/update writes it. Null when the report has none.
      - `internal_notes` string, nullable, required: The note the account keeps about this report. It is never shown to a client of the account: it belongs to whoever builds the report.
      - `type` 'report' | 'template' | 'template_based', required: `report` is a normal report, `template` one of the account's own templates, `template_based` a report whose sections are its template's.
      - `based_on_template_key` string, nullable, required: The template a template_based report follows. Null for the other two types.
      - `catalog` object, nullable, required: The catalog entry this report was materialized from, or null when it was not.
        - `slug` string, required
        - `version` integer, nullable, required
      - `created_via` 'api' | 'ui', required: Whether the report was created through this API or in the app.
      - `version` integer, required: Version of the sections structure. It is what if_version compares against, and it moves only when the list of sections changes.
      - `created_at` string, nullable, required: When the report was created, in UTC.
      - `report_level_data_sources` boolean, required: True when every widget reads from the bindings of data_sources; false when each widget carries its own connection, which is a report the API cannot extend.
      - `data_sources` ReportDataSource[], required: The report level bindings, ordered by integration. A binding without an account is not published.
        - `integration_id` string, nullable, required: Public id of the integration, or null when this source has no public id and cannot be addressed through the API.
        - `integration` string: Internal name of the source. Present only when integration_id is null.
        - `connection_key` string, nullable, required: The connection this report reads that integration from.
        - `account_id` string, nullable, required: The account inside that connection.
        - `entity` 'campaign' | 'list': mailchimp only: which of its two levels this binding is for.
      - `share_link_enabled` boolean, required: Whether the public share link of the report is on.
      - `share_link_id` string, nullable, required: The id in the public /share URL, or null when the report has never been shared.
      - `share_url` string, nullable, required: The public URL of the report, built on the account's own portal domain when it has one. Null when the report has no link.
      - `app_url` string, nullable, required: The link that opens this report in the Reporting Ninja application. Opening it requires a signed-in user of the account, so it is not the public link: `share_url` is the one anybody holding it reads. Null for a report in the trash, which the application does not open.
      - `share_link_password_set` boolean, required: Whether the link asks for a password. The password itself is never published.
      - `share_link_allow_date_range` boolean, required: Whether whoever opens the link may change the period.
      - `settings` ReportSettings: The settings window of the report, in the same shape /v1/reports/update takes it: what a read answers here is what a write sends back, whole, with no key removed and no value rewritten. Three of its keys -- `brand_template_name`, `language_file_name` and `front_cover.file` -- are published here and written by nothing: that call accepts them, ignores them, and names each one in a READ_ONLY_FIELD_IGNORED warning. Everywhere else a null means the column has no value and a write that carries it back leaves that column exactly as it is.
        - `brand_template` string, required: The brand template the report is printed with: a key of a brand template of the account, or an empty string for the system one.
        - `brand_template_name` string, nullable, required: The name of that brand template, so naming one does not need a second call. Null when the report points at a brand template that no longer exists.
        - `front_cover` ReportFrontCover, required: The front cover of the report as a read publishes it, which is the object /v1/reports/update takes back: `file` is published and not written, and it is accepted and ignored so the object can be replayed as it is.
          - `type` 'none' | 'report' | 'pdf' | 'pdf_and_report' | 'custom' | 'pdf_and_custom', required: What the front cover of the PDF is. `none` prints none, `report` draws the generated cover, `pdf` prints the uploaded file and `pdf_and_report` draws the generated text block over it. The `custom` pair is the legacy cover with texts of its own, kept and not offered: only a report already printed with one of them can be written with it again. The type commands the file: one that prints an uploaded PDF is refused on a report that carries none, and one that prints none removes the file the report carried, which the answer reports as a COVER_FILE_REMOVED warning.
          - `title` string, nullable, required: The title the generated cover prints. An empty string is a title the report does not have; null is a column that was never written.
          - `subtitle` string, nullable, required: The line under it. An empty string is a subtitle the report does not have; null is a column that was never written.
          - `date_line` 'none' | 'generation_date' | 'current_period' | 'current_and_past_period', required: The date line of the cover, of the hero of the public link and of the header of the client portal.
          - `file` ReportCoverFile, required: The PDF file the front cover prints, by name. Its content is never published.
            - `name` string, required: The name of the uploaded file.
        - `pdf` ReportPdfOptions, required: What the generated PDF carries besides the report itself.
          - `table_of_contents` boolean: Whether the PDF opens with a table of contents.
          - `page_numbers` boolean: Whether its pages are numbered.
          - `title_in_pdf` boolean: Whether the title of the report is printed on each page.
        - `localization` ReportLocalization, required: The localization of the report as a read publishes it. The six settings travel only when `use` is `report`: with `account` the report is printed with the account's, and they are the body that would put it back.
          - `use` 'account' | 'report', required: Whether the report follows the localization of the account or carries its own.
          - `date_format` 'DDMMYYYY' | 'MMDDYYYY' | 'YYYYMMDD', nullable: How dates are printed.
          - `week_starts_on` 'monday' | 'sunday', nullable: The first day of a week.
          - `decimal_separator` '.' | ',', nullable: The separator of every figure.
          - `currency` string, nullable: The currency symbol printed beside monetary figures.
          - `currency_symbol_position` 'left' | 'right', nullable: Which side of the figure the symbol is printed on.
          - `pdf_page_size` 'A4' | 'Letter', nullable: The page size of the generated PDF.
        - `language_file` string, required: The language file the report is printed with: an empty string for the system default, one of the sixteen system files (`language_file_en`, `language_file_es`, ...) or the key of a language file of the account.
        - `language_file_name` string, nullable, required: The name of that language file; a report that names none is printed with the English system file and that is the name answered here. Null when the report points at a language file of the account that no longer exists.
        - `substitution_variables` string[], required: The five substitution variables of the report, positional. An unused one is an empty string.
        - `widgets_show` ReportWidgetsShow, required: What the header of every widget of the report shows.
          - `data_source_name` boolean: Whether the name of the data source is shown.
          - `data_source_icon` boolean: Whether its icon is shown.
          - `date_range` boolean: Whether the period of the widget is shown.
        - `snapshots_with_scheduled_executions` boolean, required: Whether a snapshot of the report is stored every time it is delivered by a schedule.
        - `ai_brief` string, nullable, required: What the AI summaries of this report know about the client, or null when the report carries no brief. It is the middle of the three levels a summary reads: account, report and widget.
    - `count` integer, required: How many rows came back. The list is never paginated.
  - `meta` Meta, required
    - `request_id` string, required: Id of this request, useful when reporting an incident.
    - `timestamp` string, date-time, required: When the answer was built, in UTC.

## Other responses

- `400`: The request was refused before anything was written. INVALID_REQUEST covers the framework refusals of every endpoint (the Content-Type is not application/json, the body could not be read, the body is not valid JSON). The report endpoints add their own: VALIDATION_FAILED with details.problems, UNKNOWN_PARAM with the path of the field the endpoint does not read, and the single-field refusals MISSING_REQUIRED_FIELD, INVALID_VALUE and APPEND_NOT_ALLOWED. The description of each operation lists the ones it emits. Everything else a body can get wrong arrives as an entry of details.problems rather than as the code of the envelope.
- `401`: Invalid or missing Bearer token.
- `413`: The request body is over 1 MB. The cap is applied before authentication, so this answer is refused without the key being read, and it carries the usual error envelope.
- `429`: A budget was spent. RATE_LIMITED is the per-key read budget (300/minute, 5000/day) or the per-account write budget (60/minute, 1000/day). EMAIL_QUOTA_REACHED is the separate budget of 50 calls per account per day that send email, and its Retry-After points at the next UTC midnight. The Retry-After header gives the seconds until the more restrictive window resets. The X-RateLimit-* headers report the read budget, except on the 429 of a write, where they report the write budget.
- `500`: Internal server error.

---

[API](https://skmtc.dev/reportingninja/apis/reporting-ninja-api.md) · [All operations](https://skmtc.dev/reportingninja/apis/reporting-ninja-api/llms.txt) · [OpenAPI document](https://skmtc.dev/reportingninja/apis/reporting-ninja-api/revisions/13876c71be34?raw)
