Scheduled reports

Scheduled reports allow you to export your data on a regular basis. You can schedule daily, weekly, monthly or yearly recurrent reports.

Exports are generated on the server side, so you don't need to keep your browser open.

Your data on our servers

We don't store your data on our servers unless you have scheduled reports set up of type "download link" (we need to keep the file securely on our servers for you to download it). For these scheduled reports you can choose how long we should keep the file on our servers.

In all other cases, we do not store your data on our servers.

Creating a scheduled export

You can only create a schedule for the export configurations you own (Owner label).

Dashboard row showing owned report

To schedule a publicly visible export, create its copy (Save as... from the export configuration page) and add schedule for the copy.

The scheduling modal is accessible either from the export configuration page or from the Dashboard.

Dashboard row showing owned report without schedule
Create/edit schedule modal

Status of all the scheduled reports is visible from the Dashboard.

Options

  • Format: specify output format (CSV, XLSX, JSON)
  • Start: specify start date (useful when you want to export for example every 2nd or 3rd day)
  • Repeat: set a recurring report daily, weekly (on specificed week days), monthly (on the nth day of the month) etc.
  • Hour/Time zone: specify an hour when export should happen in specific time zone
  • Report delivery: specify how you want to receive the report (email attachment, download link, SFTP server upload, webhook POST request)

Pausing scheduled report

You can manuall pause the report by using the toggle in the upper right of the modal.

We'll also pause the report automatically after 5 or more failures in a row.

Scheduled report paused after too many failures

To reactivate the reports, go to Schedule modal and toggle the "Paused" switch in the upper right corner.

Pause toggle in the schedule modal

Receiving a scheduled export

You can receive the report in several ways:

  • email attachment
  • download link
  • SFTP server upload
  • webook POST request

Email attachment

Options for delivering report as email attachment

Options

  • Email recipients: add any Jira users as recipients. Emails will be sent to their registered email addresses
  • Optional non-Jira email addresses: add more recipients by specifying any email addresses (separated by comma)
  • Compress report: optionally compress the file attached to an email (as a ZIP file, typically 10 x smaller)
  • Email subject and body template: you can specify yuor own text for the subject and body of the emails being sent. See documentation of the syntax for templates

The scheduled reports are sent to the email addresses from Jira user profiles.

There's 25MB limit to the size of report file. If your reports tend to be big, consider using Compress report file with ZIP option which can get the file size around 10 x smaller.

Note

The emails will arrive from ae.kanbanalytics.com domain, so you may need to whitelist it in your email client.

You can also use your own account at SendGrid to send emails from different domain. See App Settings for configuration details.

Download link

Options for delivering report as download link

SFTP server upload

Options for delivering report via SFTP server upload

Webhook

Options for delivering report via webhook POST request

You can also receive the scheduled reports via webhook. The webhook is sent to the URL you specify in the Schedule settings.

Webhook will be called with POST method, with the following headers:

  • user-agent: Advanced Export/3.0.6
  • transfer-encoding: chunked
  • content-disposition: attachment; filename="FILENAME" - absent for JSON report format
  • content-type: "MIME_TYPE or application/json for JSON"
  • x-download-schedule-id: "SCHEDULE_ID"
  • x-download-schedule-execution-id: "SCHEDULE_EXECUTION_ID"

Your endpoint has to accept streamed content ("transfer-encoding: chunked").

Webhook URL can use following values:

  • {{exportConfigName}}
  • {{exportConfigId}}
  • {{reportDate}}
  • {{jql}}
  • {{format}}
  • {{rows}}
  • {{sizeMb}}

Any part of the URL containing these values will be substituted. For example:

https://example.com/report/{{exportConfigId}}?date={{reportDate}}&format={{format}}&rows={{rows}}&size={{sizeMb}}

may result in a call to:

https://example.com/report/1234-5678-9012?date=2022-03-14T08:42:00.000Z&format=CSV&rows=42&size=1.25

Example webhook endpoint implementation and test

Here's an example of the NodeJS Express based server receiving the content of the report and saving it as a file. Note the name of the file is taken from the content-disposition header.

There's no authorisation implemented below, however you can supply your custom header to use for this purpose (e.g. "Authorization: Basic XXXXXXXX").

import express from "express";
import fs from "fs";

const app = express();
app.use(express.json());

const UPLOAD_DIR = "./uploads";

app.post("/upload", (req, res) => {
    const contentDisposition = req.headers["content-disposition"];
    const contentType = req.headers["content-type"];

    if (contentType === "application/json") {
        const body = req.body;

        // process JSON data...
        console.log(body.columns);
        console.log(body.rows);

        res.sendStatus(200);
    } else if (contentDisposition) {
        // process file attachement
        let filename = "file.dat";

        const filenameRegex = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/;
        let matches = filenameRegex.exec(contentDisposition);
        if (matches != null && matches[1]) {
            filename = matches[1].replace(/['"]/g, "");
        }

        const writeStream = fs.createWriteStream(`${UPLOAD_DIR}/${filename}`);

        req.pipe(writeStream);

        writeStream.on("finish", () => {
            console.log(`Received file ${filename}, ${contentType}`);
            res.sendStatus(200);
        });

        writeStream.on("error", (err) => {
            console.error(`Error writing file: ${err.message}`);
            res.sendStatus(500);
        });
    }
});

app.listen(3002, () => {
    console.log("Server listening on port 3002");
});

This code and more example is available in the GitHub repository

To test it:

  • Save the above code as server.js
  • Run the server locally with node server.js
  • Use ngrok to expose it to the internet:
ngrok http 3002
  • Use the ngrok tunnel as the webhook URL in the schedule settings, e.g. https://xxxx-xxxx-xxxx.ngrok-free.app/upload (note the /upload path).

  • You can then use "Execute now" button in the Schedule modal to execute and test the webhook.

Execute now button in the Schedule modal