Schedule Exports in Dashboards

In dashboards, you can schedule exports that send the dashboard as a PDF file, or a widget as CSV or XLSX tabular exports, at scheduled intervals.

Delivery Methods

When a scheduled export is triggered, the exported file will be delivered based on the selected destination. If an email destination is chosen, you’ll receive a structured email linking to the original dashboard and with the exported file attached to the email:

Screenshot of the scheduled export email template.

Alternatively, if a webhook destination is selected, a JSON payload will be sent to the webhook for further processing in external systems, managed by the administrator.

Schedule Export

Scheduled exports can be either of the entire dashboard, or an individual widget.

Dashboard

Follow the steps below to set up a new scheduled export of a dashboard:

UI
API

Steps:

  1. Open a dashboard.

  2. In the top right corner, click the button and select Schedule export.

    Screenshot of the ... menu highlighting the Schedule export option.

    The scheduled export creation dialog opens.

  3. Set the frequency, email recipients, and email content. Note that only you and other users with access to the dashboard can be included in the recipients.

    ...

    Then click Create.

    Your automated PDF export is scheduled.

To create and manage scheduled exports via the API, you need to first create an export definition using the API endpoint /api/v1/entities/workspaces/<workspaceId>/exportDefinitions, and then you can call the API endpoint /api/v1/entities/workspaces/<workspaceId>/automations to schedule the export.

Steps:

  1. Create an export definition of the dashboard:

    curl $HOST_URL/api/v1/entities/workspaces/<workspace_id>/exportDefinitions \
      -H "Content-Type: application/vnd.gooddata.api+json" \
      -H "Accept: application/vnd.gooddata.api+json" \
      -H "Authorization: Bearer $API_TOKEN" \
      -X POST \
      -d '{
        "data": {
          "type": "exportDefinition",
          "attributes": {
            "title": "<export_definition_title>",
            "requestPayload": {
              "fileName": "<export_definition_filename>",
              "dashboardId": "<dashboard_id>"
            }
          }
        }
      }'
    

    you should receive a <export_definition_id>.

  2. Create the scheduled export using the <export_definition_id> from previous step:

    curl $HOST_URL/api/v1/entities/workspaces/<workspace_id>/automations \
      -H "Content-Type: application/vnd.gooddata.api+json" \
      -H "Accept: application/vnd.gooddata.api+json" \
      -H "Authorization: Bearer $API_TOKEN" \
      -X POST \
      -d '{
        "data": {
          "type": "automation",
          "id": "<scheduled_export_id>",
          "attributes": {
            "title": "<scheduled_export_display_name>",
            "details": {
              "message": "<export_body_text>",
              "subject": "<export_subject>"
            },
            "schedule": {
              "firstRun": "<timestamp>",
              "timezone": "<timezone>",
              "cron": "<cron_expression>"
            }
          },
          "relationships": {
            "exportDefinitions": {
              "data": [
                {
                  "type": "exportDefinition",
                  "id": "<export_definition_id>"
                }
              ]
            },
            "recipients": {
              "data": [
                {
                  "type": "user",
                  "id": "<user_id>"
                }
              ]
            },
            "notificationChannel": {
              "data": {
                "type": "notificationChannel",
                "id": "<destination_id>"
              }
            },
            "analyticalDashboard": {
              "data": {
                "type": "analyticalDashboard",
                "id": "<dashboard_id>"
              }
            }
          }
        }
      }'
    

A real-life example might look like this:

  1. Creating export definition:

    curl https://frosty-cat.trial.cloud.gooddata.com/api/v1/entities/workspaces/e45864d8057f40a09957ba1cdd3b5129/exportDefinitions \
      -H "Content-Type: application/vnd.gooddata.api+json" \
      -H "Accept: application/vnd.gooddata.api+json" \
      -H "Authorization: Bearer YWRtaW46Ym9vdHN0cmFwOkdkY05hczEyMw==" \
      -X POST \
      -d '{
        "data": {
          "type": "exportDefinition",
          "attributes": {
            "title": "Overview",
            "requestPayload": {
              "fileName": "Overview",
              "dashboardId": "2f0b76a1-9e8e-4375-84be-721919e02cb7"
            }
          }
        }
      }'
    

    The export definition ID is returned as 8b857896-9cbc-4f37-8fc3-3b491945b9a2.

  2. Scheduling export:

    curl https://frosty-cat.trial.cloud.gooddata.com/api/v1/entities/workspaces/e45864d8057f40a09957ba1cdd3b5129/automations \
      -H "Content-Type: application/vnd.gooddata.api+json" \
      -H "Accept: application/vnd.gooddata.api+json" \
      -H "Authorization: Bearer YWRtaW46Ym9vdHN0cmFwOkdkY05hczEyMw==" \
      -X POST \
      -d '{
        "data": {
          "type": "automation",
          "id": "9dab9b5e-a822-4b15-b8db-cd5cdbe73deb",
          "attributes": {
            "title": "Overview dashboard",
            "details": {
              "message": "Hello,\n\nthis is an export of the overview dashboard.",
              "subject": "Overview dashboard"
            },
            "schedule": {
              "firstRun": "2024-10-01T12:00:00Z",
              "timezone": "Europe/Amsterdam",
              "cron": "0 0 14 ? * TUE"
            }
          },
          "relationships": {
            "exportDefinitions": {
              "data": [
                {
                  "type": "exportDefinition",
                  "id": "8b857896-9cbc-4f37-8fc3-3b491945b9a2"
                }
              ]
            },
            "recipients": {
              "data": [
                {
                  "type": "user",
                  "id": "alex.doe"
                }
              ]
            },
            "notificationChannel": {
              "data": {
                "type": "notificationChannel",
                "id": "a5b13b1b-4e60-4a6d-bba6-9b2b4ec96988"
              }
            },
            "analyticalDashboard": {
              "data": {
                "type": "analyticalDashboard",
                "id": "2f0b76a1-9e8e-4375-84be-721919e02cb7"
              }
            }
          }
        }
      }'
    

Widget

Follow the steps below to set up a new scheduled export of an individual widget:

UI
API

Steps:

  1. Open a dashboard.

  2. Click the menu on a widget and select Schedule export:

    ...
  3. Set the frequency, email recipients, and email content:

    ...

    Note that only you and other users with access to the dashboard can be included in the recipients.

    The dialog includes XLSX export options and the ability to disable merged attribute cells in XLSX exports:

    ...

    For example, by default, an exported visualization in XLSX format might look like this:

    ContinentCountry
    EuropeFrance
    Germany

    If you disable the Keep attribute cells merged option, the XLSX table will look like this:

    ContinentCountry
    EuropeFrance
    EuropeGermany
  4. Click Create.

To create and manage scheduled exports via the API, you need to first create an export definition using the API endpoint /api/v1/entities/workspaces/<workspaceId>/exportDefinitions, and then you can call the API endpoint /api/v1/entities/workspaces/<workspaceId>/automations to schedule the export.

If you want to export the widget both as CSV and as XLSX files, you need to create two export definitions.

Steps:

  1. Create a XLSX export definition of the widget:

    curl $HOST_URL/api/v1/entities/workspaces/<workspace_id>/exportDefinitions \
          -H "Content-Type: application/vnd.gooddata.api+json" \
          -H "Accept: application/vnd.gooddata.api+json" \
          -H "Authorization: Bearer $API_TOKEN" \
          -X POST \
          -d '{
            "data": {
              "type": "exportDefinition",
              "attributes": {
                "title": "<export_definition_xlsx_title>",
                "requestPayload": {
                  "fileName": "<export_definition_xlsx_filename>",
                  "format": "XLSX",
                  "visualizationObject": "<visualization_id>",
                  "visualizationObjectCustomFilters": [
                    {
                      "negativeAttributeFilter": {
                        "localIdentifier": "<arbitraty_id>",
                        "displayForm": {
                          "identifier": {
                            "id": "<label_id>",
                            "type": "label"
                          }
                        },
                        "notIn": {
                          "values": [
                            "Direct",
                            "PR"
                          ]
                        }
                      }
                    }
                  ],
                  "relatedDashboardId": "<dashboard_id>",
                  "settings": {
                    "mergeHeaders": true
                  },
                  "metadata": {
                    "widget": "<widget_id>"
                  }
                }
              }
            }
          }'
    

    you should receive a <export_definition_xlsx_id>.

  2. Create a CSV export definition of the widget:

    curl $HOST_URL/api/v1/entities/workspaces/<workspace_id>/exportDefinitions \
          -H "Content-Type: application/vnd.gooddata.api+json" \
          -H "Accept: application/vnd.gooddata.api+json" \
          -H "Authorization: Bearer $API_TOKEN" \
          -X POST \
          -d '{
            "data": {
              "type": "exportDefinition",
              "attributes": {
                "title": "<export_definition_csv_title>",
                "requestPayload": {
                  "fileName": "<export_definition_csv_filename>",
                  "format": "CSV",
                  "visualizationObject": "<visualization_id>",
                  "visualizationObjectCustomFilters": [
                    {
                      "negativeAttributeFilter": {
                        "localIdentifier": "<arbitraty_id>",
                        "displayForm": {
                          "identifier": {
                            "id": "<label_id>",
                            "type": "label"
                          }
                        },
                        "notIn": {
                          "values": [
                            "Direct",
                            "PR"
                          ]
                        }
                      }
                    }
                  ],
                  "relatedDashboardId": "<dashboard_id>",
                  "settings": {},
                  "metadata": {
                    "widget": "<widget_id>"
                  }
                }
              }
            }
          }'
    

    you should receive a <export_definition_csv_id>.

  3. Create the scheduled export using the <export_definition_csv_id> and <export_definition_xlsx_id> from previous steps:

    curl $HOST_URL/api/v1/entities/workspaces/<workspace_id>/automations \
          -H "Content-Type: application/vnd.gooddata.api+json" \
          -H "Accept: application/vnd.gooddata.api+json" \
          -H "Authorization: Bearer $API_TOKEN" \
          -X POST \
          -d '{
            "data": {
              "type": "automation",
              "id": "<scheduled_export_id>",
              "attributes": {
                "title": "<scheduled_export_display_name>",
                "details": {
                  "message": "<export_body_text>",
                  "subject": "<export_subject>"
                },
                "schedule": {
                  "firstRun": "<timestamp>",
                  "timezone": "<timezone>",
                  "cron": "<cron_expression>"
                }
              },
              "relationships": {
                "exportDefinitions": {
                  "data": [
                    {
                      "type": "exportDefinition",
                      "id": "<export_definition_xlsx_id>"
                    },
                    {
                      "type": "exportDefinition",
                      "id": "<export_definition_csv_id>"
                    }
                  ]
                },
                "recipients": {
                  "data": [
                    {
                      "type": "user",
                      "id": "<user_id>"
                    }
                  ]
                },
                "notificationChannel": {
                  "data": {
                    "type": "notificationChannel",
                    "id": "<destination_id>"
                  }
                },
                "analyticalDashboard": {
                  "data": {
                    "type": "analyticalDashboard",
                    "id": "<dashboard_id>"
                  }
                }
              }
            }
          }'
    

A real-life example might look like this:

  1. Creating XLSX export definition:

    curl https://frosty-cat.trial.cloud.gooddata.com/api/v1/entities/workspaces/e45864d8057f40a09957ba1cdd3b5129/exportDefinitions \
          -H "Content-Type: application/vnd.gooddata.api+json" \
          -H "Accept: application/vnd.gooddata.api+json" \
          -H "Authorization: Bearer YWRtaW46Ym9vdHN0cmFwOkdkY05hczEyMw==" \
          -X POST \
          -d '{
            "data": {
              "type": "exportDefinition",
              "attributes": {
                "title": "Spend by Category and Type",
                "requestPayload": {
                  "fileName": "Spend by Category and Type",
                  "format": "XLSX",
                  "visualizationObject": "aba6ab91-b013-4aa0-9b48-aa8cfd33f017",
                  "visualizationObjectCustomFilters": [
                    {
                      "negativeAttributeFilter": {
                        "localIdentifier": "3fbc2bc2b2ce4cdeaa12ea2f8e67e137",
                        "displayForm": {
                          "identifier": {
                            "id": "campaign_channels.category",
                            "type": "label"
                          }
                        },
                        "notIn": {
                          "values": [
                            "Direct",
                            "PR"
                          ]
                        }
                      }
                    }
                  ],
                  "relatedDashboardId": "2f0b76a1-9e8e-4375-84be-721919e02cb7",
                  "settings": {
                    "mergeHeaders": true
                  },
                  "metadata": {
                    "widget": "eda05736-faba-4336-8da0-991a79e9862a"
                  }
                }
              }
            }
          }
    

    The XLSX export definition ID is returned as 5100cfb0-a486-4023-832b-a667ac70d1d0.

  2. Creating CSV export definition:

    curl https://frosty-cat.trial.cloud.gooddata.com/api/v1/entities/workspaces/e45864d8057f40a09957ba1cdd3b5129/exportDefinitions \
          -H "Content-Type: application/vnd.gooddata.api+json" \
          -H "Accept: application/vnd.gooddata.api+json" \
          -H "Authorization: Bearer YWRtaW46Ym9vdHN0cmFwOkdkY05hczEyMw==" \
          -X POST \
          -d '{
            "data": {
              "type": "exportDefinition",
              "attributes": {
                "title": "Spend by Category and Type",
                "requestPayload": {
                  "fileName": "Spend by Category and Type",
                  "format": "CSV",
                  "visualizationObject": "aba6ab91-b013-4aa0-9b48-aa8cfd33f017",
                  "visualizationObjectCustomFilters": [
                    {
                      "negativeAttributeFilter": {
                        "localIdentifier": "3fbc2bc2b2ce4cdeaa12ea2f8e67e137",
                        "displayForm": {
                          "identifier": {
                            "id": "campaign_channels.category",
                            "type": "label"
                          }
                        },
                        "notIn": {
                          "values": [
                            "Direct",
                            "PR"
                          ]
                        }
                      }
                    }
                  ],
                  "relatedDashboardId": "2f0b76a1-9e8e-4375-84be-721919e02cb7",
                  "settings": {},
                  "metadata": {
                    "widget": "eda05736-faba-4336-8da0-991a79e9862a"
                  }
                }
              }
            }
          }
    

    The CSV export definition ID is returned as 4e5c77aa-48e1-4398-bd73-c06cdbdaf2d6.

  3. Scheduling export:

curl https://frosty-cat.trial.cloud.gooddata.com/api/v1/entities/workspaces/e45864d8057f40a09957ba1cdd3b5129/automations \
      -H "Content-Type: application/vnd.gooddata.api+json" \
      -H "Accept: application/vnd.gooddata.api+json" \
      -H "Authorization: Bearer YWRtaW46Ym9vdHN0cmFwOkdkY05hczEyMw==" \
      -X POST \
      -d '{
        "data": {
          "type": "automation",
          "id": "829a9370-0555-4050-a6ae-c94fc49ea0ee",
          "attributes": {
            "title": "Spend Bar Chart",
            "details": {
              "message": "Hello,\n\nthis is an export of the spend bar chart as CSV and XLSX file.",
              "subject": "Spend bar chart"
            },
            "schedule": {
              "firstRun": "2024-10-01T13:00:00Z",
              "timezone": "Europe/Amsterdam",
              "cron": "0 0 15 ? * *"
            }
          },
          "relationships": {
            "exportDefinitions": {
              "data": [
                {
                  "type": "exportDefinition",
                  "id": "5100cfb0-a486-4023-832b-a667ac70d1d0"
                },
                {
                  "type": "exportDefinition",
                  "id": "4e5c77aa-48e1-4398-bd73-c06cdbdaf2d6"
                }
              ]
            },
            "recipients": {
              "data": [
                {
                  "type": "user",
                  "id": "alex.doe"
                }
              ]
            },
            "notificationChannel": {
              "data": {
                "type": "notificationChannel",
                "id": "a5b13b1b-4e60-4a6d-bba6-9b2b4ec96988"
              }
            },
            "analyticalDashboard": {
              "data": {
                "type": "analyticalDashboard",
                "id": "2f0b76a1-9e8e-4375-84be-721919e02cb7"
              }
            }
          }
        }
      }

Filters

When creating a scheduled export, the active dashboard filters are saved as part of the scheduled export, and all exports will use those filter values.

In case of dashboard exports, you can disable this behavior by clicking the edited dashboard filters text and toggling Use default filters:

...

In this case, the default filters will be used - if the dashboard’s default filter values are changed in the future, these new filter values will NOT be applied to this scheduled export.

Cron Expressions

For scheduled exports, you can define a custom schedule using a cron expression. GoodData supports a six-field UNIX cron format: second minute hour day month year. For example, the cron expression 0 0 15 ? * * will trigger the export daily at 15:00.

Screenshot of part of the schedule export dialog highlighting the Repeats setting that is set to a cron expression.

To create valid cron expressions, you can use online tools like the Free Formatter’s cron expression generator.

GoodData supports sending scheduled exports at most once per hour.

Disabling

You can disable the option to create new scheduled exports for a specific visualization by editing it in the Analytical Designer. To do this, go to the Interactions tab while editing the visualization:

Screenshot of the interaction tab in the analytical designer.