Skip to main content
This functionality is currently in public beta. You can opt into this beta via the associated product update in your HubSpot account.By participating in this beta, you agree to HubSpot’s Developer Terms and Developer Beta Terms. Note that the functionality is still under active development and is subject to change based on testing and feedback.
Use the reporting API to manage the reports and dashboards in your account. For example, batch-update the owner of a set of dashboards, share a report with your team by email, or clone an existing dashboard for a new business unit. Learn more about using reports and dashboards in HubSpot.

What’s supported in this beta

This beta supports managing the metadata of reports and dashboards, including reading, searching, updating, restoring, archiving, exporting, and managing ownership, permissions, and dashboard widgets. It does not yet support a report’s configuration — the underlying query and visualization that define what a report shows. As a result, you cannot currently:
  • Create a report (a report can’t be created without its configuration).
  • Read or update a report’s configuration.
Reading and updating report metadata (such as its name, description, owner, and permissions) is fully supported. The reporting team is actively working toward a unified, publicly consumable way to declare a report’s configuration. This is a high priority, and support for report creation and configuration is expected to be added incrementally over the course of this beta.

Scope requirements

This API uses the following scopes:
  • reporting.full.read permits all read operations, including retrieving, searching, and exporting reports and dashboards.
  • reporting.full.edit permits update operations, including updating report and dashboard metadata and adding reports to or removing reports from dashboards. It does not permit creating or deleting objects.
  • reporting.full.write permits all write operations, including creating, archiving, restoring, and batch operations. It is a superset of reporting.full.edit.
  • reporting.full.admin permits all operations and additionally grants administrative access. For apps with user-level access, it lets users who are reporting or super admins exercise their full administrative access. For example, this gives them access to all reporting objects, including ones that would otherwise be private. It isn’t relevant for apps with account-level access, since those already act as administrators within the bounds of their authorized scopes.
A request needs only one scope that covers the operation being performed.
Please note:
  • Updating an object requires at least reporting.full.edit. However, from an app with user-level access, if the requesting user isn’t the object’s owner, updating the ownerUserId, permissions, or businessUnitId requires reporting.full.write or reporting.full.admin instead.
  • Export endpoints are available to apps with user-level access only. Calling an /export endpoint from an app with account-level access (including legacy apps) will fail, because a real user is required to trigger an export.

Reading dashboards and reports

The easiest way to get familiar with the API is to retrieve existing data from your account. You can retrieve a single object by ID or search for a page of objects.

Retrieve a single dashboard or report

To retrieve a single dashboard, make a GET request to /analytics/reporting/2027-03-beta/dashboards/{dashboardId}. To retrieve a single report, make a GET request to /analytics/reporting/2027-03-beta/reports/{reportId}. By default, a core set of properties is returned. To include additional properties that aren’t returned by default, add a properties query parameter. Retrieving an archived object requires you to be the object’s owner, a reporting admin, or a super admin. For example, to retrieve a dashboard along with its widgets and permissions, your request URL would look like /analytics/reporting/2027-03-beta/dashboards/4815162342?properties=widgets&properties=permissions.

Search for dashboards or reports

To search for dashboards, make a GET request to /analytics/reporting/2027-03-beta/dashboards. To search for reports, make a GET request to /analytics/reporting/2027-03-beta/reports. Both endpoints return a paginated collection with a total count.
Search is eventually consistent. Changes to reporting objects may take a few seconds to be reflected in search results.
You can include the following query parameters to filter, sort, and paginate the results. The /reports endpoint also supports two additional filters: For example, to retrieve the first 50 dashboards owned by a specific user, sorted by name, your request URL would look like /analytics/reporting/2027-03-beta/dashboards?ownerUserIds=11045285&sort=name&limit=50.
When searching archived objects with archived=true, only limit and after are respected — filtering, custom sorting, and additional property projection are ignored. Results are always ordered from most recently to least recently deleted, and only your own archived objects are returned unless you’re a reporting or super admin.

Creating a dashboard

To create a dashboard, make a POST request to /analytics/reporting/2027-03-beta/dashboards, and provide a name and permissions object in the body of your request.
There is no endpoint to create a report in this beta, because a report can’t be created without its configuration. See What’s supported in this beta.
You can include the following properties in the request body. For example, to create a private dashboard with two existing reports attached, your request body would look like:
Attaching reports at creation time is best-effort — some or all reports may fail to attach, but the dashboard is still created and no error is returned. A maximum of 50 reports can appear on a dashboard. Check the widgets field in the response to confirm which reports were attached.

Cloning a dashboard

To clone an existing dashboard, make a POST request to /analytics/reporting/2027-03-beta/dashboards/{dashboardId}/clone, and provide a name and permissions object in the body of your request.

Updating a dashboard or report

To update a dashboard, make a PATCH request to /analytics/reporting/2027-03-beta/dashboards/{dashboardId}. To update a report, make a PATCH request to /analytics/reporting/2027-03-beta/reports/{reportId}. Only the properties you include in the request body are updated.
Updating an object requires at least reporting.full.edit. However, when requesting from an app with user-level access, if the requesting user is not the object’s owner, attempting to update the ownerUserId, permissions, or businessUnitId will require reporting.full.write or reporting.full.admin instead.
For example, to rename a report and reassign its owner, your request body would look like:

Archiving and restoring

Archiving is a soft delete. Archived objects can be retrieved and restored, but are permanently purged 90 days after they’re archived. There are two ways to archive or restore an object.

Archive or restore a single object

Set the archived field in a PATCH request to the object. When archived is present, it must be the only property in the request body, or the request returns an error. Attempting to archive an already-archived object, or restore an already-active object, is a no-op and returns a successful response.

Archive or restore in batch

To archive multiple objects at once, make a POST request to /analytics/reporting/2027-03-beta/dashboards/batch/archive or /analytics/reporting/2027-03-beta/reports/batch/archive. To restore, use the corresponding /batch/restore endpoints. In the request body, include the object IDs. The maximum batch size is 500. Batch archive silently ignores already-archived objects, and batch restore silently ignores already-active ones. For example, to archive three dashboards, your request body would look like:

Managing dashboard widgets

A dashboard’s reports are represented as widgets.
A dashboard can hold up to 50 reports. If a request would take a dashboard beyond that limit, it fails.

Add a single report

To add one report to a dashboard, make a PUT request to /analytics/reporting/2027-03-beta/dashboards/{dashboardId}/widgets/{reportId}. No request body is required. The widget is appended to the end of the dashboard’s layout. If the report is already on the dashboard, doesn’t exist, or you don’t have permission to access it, the request does nothing. The dashboard in the response reflects whether the report was added.

Add reports in batch

To add multiple reports to a dashboard, make a POST request to /analytics/reporting/2027-03-beta/dashboards/{dashboardId}/batch/widgets, and include the report IDs in the request body. Widgets are appended in the order provided, and any reports that are already on the dashboard, don’t exist, or aren’t accessible are skipped. The dashboard in the response reflects which reports were added.

Remove a report

To remove one report from a dashboard, make a DELETE request to /analytics/reporting/2027-03-beta/dashboards/{dashboardId}/widgets/{reportId}. No request body is required.

Batch updating owners and permissions

You can reassign ownership or update permissions for many objects in a single request. All batch endpoints have a maximum batch size of 500.

Batch update owners

To update the owner of multiple objects, make a POST request to /analytics/reporting/2027-03-beta/dashboards/owners/batch/update or /analytics/reporting/2027-03-beta/reports/owners/batch/update. In the request body, include the object IDs and the ownerUserId of the new owner.

Batch update permissions

To update permissions for multiple objects, make a POST request to /analytics/reporting/2027-03-beta/dashboards/permissions/batch/update or /analytics/reporting/2027-03-beta/reports/permissions/batch/update. In the request body, include the object IDs and a permissions object. See Managing permissions for the shape of the permissions object.

Managing permissions

The object’s owner and any super or reporting admin always have full permissions. For everyone else, access is governed by the permissionType field in the permissions object. When permissionType is SPECIFIC, include a specificPermissions configuration. Each configuration has a permissionType of VIEW or EDIT and a grants array, where each grant has a grantType of USER or TEAM and a granteeId. Dashboards and reports differ in how many specific configurations they accept:
  • Dashboards accept up to two configurations — one VIEW and/or one EDIT. Each user or team receives the level of the configuration they’re listed in.
  • Reports accept exactly one configuration — either VIEW or EDIT, not both.
For example, to grant edit access to a specific team and view access to a specific user on a dashboard, the permissions object would look like:
When a report is on one or more dashboards, it inherits the aggregate permissions of all dashboards it’s on instead of having its own permissions. You cannot set a report’s permissions if it is on any dashboard, and attempting to do so will result in an error.

Exporting dashboards and reports

To export a dashboard, make a POST request to /analytics/reporting/2027-03-beta/dashboards/{dashboardId}/export. To export a report, make a POST request to /analytics/reporting/2027-03-beta/reports/{reportId}/export. The export is delivered to one or more HubSpot users through standard channels, primarily email.
Export endpoints are available to apps with user-level access only, and there is no status tracking — a successful request returns a 204 No Content. If a recipient doesn’t have access to reporting or doesn’t have CRM export permissions, they receive a notification describing the error rather than a successful export.
You can include the following fields in the request body. Dashboard exports also support a reportIds array — if non-empty, only the specified reports are included in the export. Supported exportType values differ by object: For dashboards, SCREENSHOT produces individual report screenshots, while PDF, PPTX, and ZIP bundle those screenshots into a single file. The CSV, XLS, and XLSX types each produce a ZIP containing one or more data files per report. For example, to email a PDF of a dashboard to two users, your request body would look like:
Last modified on September 15, 2026