# Reports

After a user completes a measurement or when the prescription period ends, the user and physician receive (periodic) reports with results and insights into the measurement(s).

## Request a measurement report and render the PDF

### SDK

The `getMeasurementReportUrl` method accepts a `measurementId` and handles the creation and fetching of the report.

* The first time you execute this function for a measurement, it will take a little longer. The cloud service will render the report synchronously. Once it's ready (\~5s) a URL will be returned. The report is available at this URL.
* Subsequent calls will be much faster, as the report is already rendered and the URL will be returned almost instantly.
* The PDF will always be rendered in the user's language. This is the language that was specified during the user's registration process. Currently, the supported languages are: `de`, `en`, `es`, `fr`, `it`, `nl`, `ar` and `zh`. When other languages are provided, the report will fall back to the default language `en`.

{% tabs %}
{% tab title="Flutter" %}
This functionality works great in combination with [url\_launcher](https://pub.dev/packages/url_launcher).

```dart
import 'package:url_launcher/url_launcher.dart';
import 'package:flutter_fibricheck_sdk/flutter_fibricheck_sdk.dart';

_reportUrl = await _sdk.getMeasurementReportUrl(widget.measurement.id!);

Future<void> _launchUrl() async {
    final url = Platform.isAndroid ? "https://docs.google.com/viewer?url=$reportUrl" : reportUrl;
    if (await canLaunchUrl(Uri.parse(url))) {
      if (!await launchUrl(Uri.parse(url))) {
        throw 'Could not launch $reportUrl';
      }
    }
  }
```

{% endtab %}

{% tab title="React Native" %}
This functionality works great in combination with `react-native-pdf` or `react-native-share`.

```typescript
import Pdf from 'react-native-pdf';

const measurementId = '0000';

const App = () => {
  const [uri, setUri] = useState();

  useEffect(() => {
    (async () => {
      const uri = await sdk.getReportUrl(measurementId);
      setUri(uri);
    })();
  }, []);

  return (
    <Pdf
      source={{
        uri,
      }}
    />
  );
};  
```

{% endtab %}
{% endtabs %}

### REST API

Rendering a PDF report using the REST API takes 3 simple steps.\
The first step is only needed when no report has been created yet.

#### Step 1 • Generate a report

## Generate a new report

<mark style="color:green;">`POST`</mark> `https://api.fibricheck.com/data/v1/measurement-reports/documents`

{% tabs %}
{% tab title="200: OK " %}

```javascript
{
    "query": "{\"$and\":[{\"data.measurementId\":{\"$eq\":\"63ee4771e8c20b1bfb1bf617\"}},{\"$or\":[{\"$and\":[{\"userIds\":{\"$eq\":\"5811c7a046e0fb000530a465\"}}]},{\"$and\":[{\"groupIds\":{\"$in\":[\"5919759152faff000545b18c\"]}}]}]}]}",
    "page": {
        "total": 1,
        "offset": 0,
        "limit": 1
    },
    "data": [
        {
            "id": "63ee47a8e8c20b8ab31bfbeb",
            "groupIds": [],
            "userIds": [
                "5811c7a046e0fb000530a465"
            ],
            "creatorId": "5811c7a046e0fb000530a465",
            "status": "rendered",
            "statusChangedTimestamp": "2023-02-16T15:11:40.246Z",
            "data": {
                "measurementId": "63ee4771e8c20b1bfb1bf617",
                "language": "EN",
                "forMeasurementUpdatedTimestamp": 1676560280650,
                "readFileToken": "63ee47ac7e2b7133cf59c983-5ec781dc-1616-4793-8dd7-31dfa764d947"
            },
            "updateTimestamp": "2023-02-16T15:11:40.250Z",
            "creationTimestamp": "2023-02-16T15:11:36.698Z"
        }
    ]
}
```

{% endtab %}
{% endtabs %}

This API call should be executed with the following body to trigger a report creation:

```javascript
{
    "measurementId" : "{measurementId}"
    "language": "EN"
}
```

* &#x20;`measurementId` identifies the measurement for which you want to generate a report.
* `language` defines the language in which the report will be generated. It is advised to use the user's set language.

{% hint style="info" %}
The report is generated in the timezone of the user that performed the measurement. Once a report is generated, it's not possible to change the timezone anymore. To change the timezone of the report, you have to change the timezone of the user.
{% endhint %}

{% hint style="warning" %}
To generate a report for a measurement, make sure that the measurement [status](/introduction/measurements.md#status) is set to`analyzed, pending-review` or `reviewed`
{% endhint %}

#### Step 2 • Fetch the report file token

Using the `measurementId` from the measurement, execute the API call below. This will return the latest generated report.&#x20;

## Fetch report details

<mark style="color:blue;">`GET`</mark> `https://api.fibricheck.com/data/v1/measurement-reports/documents?limit(1)&sort(-id)&eq(data.measurementId,{measurementId})`

#### Query Parameters

| Name          | Type | Description |
| ------------- | ---- | ----------- |
| measurementId |      |             |

{% tabs %}
{% tab title="200: OK " %}

```javascript
{
    "query": "{\"$and\":[{\"data.measurementId\":{\"$eq\":\"63ee4771e8c20b1bfb1bf617\"}},{\"$or\":[{\"$and\":[{\"userIds\":{\"$eq\":\"5811c7a046e0fb000530a465\"}}]},{\"$and\":[{\"groupIds\":{\"$in\":[\"5919759152faff000545b18c\"]}}]}]}]}",
    "page": {
        "total": 1,
        "offset": 0,
        "limit": 1
    },
    "data": [
        {
            "id": "63ee47a8e8c20b8ab31bfbeb",
            "groupIds": [],
            "userIds": [
                "5811c7a046e0fb000530a465"
            ],
            "creatorId": "5811c7a046e0fb000530a465",
            "status": "rendered",
            "statusChangedTimestamp": "2023-02-16T15:11:40.246Z",
            "data": {
                "measurementId": "63ee4771e8c20b1bfb1bf617",
                "language": "EN",
                "forMeasurementUpdatedTimestamp": 1676560280650,
                "readFileToken": "63ee47ac7e2b7133cf59c983-5ec781dc-1616-4793-8dd7-31dfa764d947"
            },
            "updateTimestamp": "2023-02-16T15:11:40.250Z",
            "creationTimestamp": "2023-02-16T15:11:36.698Z"
        }
    ]
}
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Best Practice**

We recommend to compare `data.forMeasurementUpdatedTimestamp` from the report with value with the `updateTimestamp` from the measurement. \
If the measurement timestamp is later than the report timestamp, a new report should be generated (see step 1) because the measurement data has been updated.&#x20;
{% endhint %}

If `data.status` is set to `rendered`, the PDF report is available for downloading.&#x20;

#### Step 3 • Fetch the PDF report URL

Using `data.readFileToken`  from step 2 you can construct the URL at which the PDF is available:

```
https://api.fibricheck.com/files/v1/{readFileToken}/file
```

This endpoint is publicly available.&#x20;

## Request periodic reports

Periodic reports are generated automatically on predetermined timeframes. This can be manual, 7 days, 30 days or at the end of a prescription.

{% hint style="warning" %}
**Note that B2C Essential users will not receive periodic reports!**
{% endhint %}

### SDK

The `getPeriodicReports` method returns a paginated result with all periodic reports for the authenticated user. You can find the measurements from that period in the `data.measurements` property. You can also use the `next` and `previous` methods available on the result to navigate through the user's measurements.

In periodic reports, the `trigger` field indicates for which period the report was made. This can be 7 days, 30 days or at the end of a prescription.

The `getPeriodicReportPdf` method retrieves a PDF version of the report. This method takes a `reportId` as a parameter. The PDF is rendered in the user's language.

{% tabs %}
{% tab title="Flutter" %}

```dart
import 'package:flutter_fibricheck_sdk/flutter_fibricheck_sdk.dart';

_sdk.getPeriodicReports(true); // true -> get newest reports first
await res.getNextPagedPeriodicReportsResult(); // get next 20 reports
await res.getPreviousPagedPeriodicReportsResult(); // get previous 20 reports


// To request a specific report in PDF format, use the following method 
await _sdk.getPeriodicReportPdf(reportId);
```

If you save the PDF you could render it in the app with a package such as <https://pub.dev/packages/pdf_render>
{% endtab %}

{% tab title="React Native" %}
The method is a [generator function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function*) that returns an [iterator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Iterators_and_Generators). This iterator can be called with `.next()` to retrieve the next 20 reports. Another way to do this is by using the for await construction, as seen in the example.

```typescript
import client from '@fibricheck/javascript-sdk';

interface PeriodicReport {
  id: string;
  status: string;
  trigger: 'PERIOD_DAYS_PASSED_7' | 'PERIOD_DAYS_PASSED_30' | 'PRESCRIPTION_ENDED'; 
  creationTimestamp: number;
}

const sdk = client({
  consumerKey: '',
  consumerSecret: '',
});

await sdk.authenticate({
  token: '',
  tokenSecret: '',
});

const reportsIterator = await sdk.getPeriodicReports();

for await (const reportsPage of reportsIterator) {
  ... /* PagedResult<PeriodReport> */
}
```

Here's an example of how to convert the response to a PDF using [react-native-share](https://github.com/react-native-share/react-native-share):

```typescript
import client from '@fibricheck/javascript-sdk';
import Share from 'react-native-share';

const sdk = client({
  consumerKey: '',
  consumerSecret: '',
});

await sdk.authenticate({
  token: '',
  tokenSecret: '',
});

const report = await sdk.getPeriodicReportPdf('62441ce00000000000000000');
const base64 = Buffer.from(file.data, 'binary').toString('base64');
const file = `data:application/pdf;base64,${base64}`;
const filename = file.headers['content-disposition'].split('filename="')[1].split('.pdf"')[0];

await Share.open({
  title: filename,
  type: 'application/pdf',
  filename: filename,
  url: file,
});
```

{% endtab %}
{% endtabs %}

### REST API

## Get periodic reports

<mark style="color:blue;">`GET`</mark> `https://api/reports/v1?sort(-creation_timestamp)&user_id={userId}`

This API call returns a list of periodic reports for a given user

#### Query Parameters

| Name   | Type | Description                                  |
| ------ | ---- | -------------------------------------------- |
| userId |      | The user for which you want to fetch reports |

{% tabs %}
{% tab title="200: OK " %}

```javascript
{
    "query": "{ {\"user_id\": {\"$oid\": \"5a2e547a46e0fb00053adfc2\"}, \"group_id\": {\"$in\": [{\"$oid\": \"5919759152faff000545b18c\"}]}}  }",
    "page": {
        "total": 9,
        "offset": 0,
        "limit": 20
    },
    "data": [
        {
            "id": "5bfaaef96522050007a622d7",
            "group_id": "5919759152faff000545b18c",
            "user_id": "5a2e547a46e0fb00053adfc2",
            "content": {
                "start_timestamp": 1540559595630,
                "end_timestamp": 1543151595630
            },
            "status": "COMPLETE",
            "trigger": "PERIOD_DAYS_PASSED_30",
            "tags": [
                "not_sent"
            ],
            "status_updated_timestamp": 1543156291414,
            "creation_timestamp": 1543155449711,
            "update_timestamp": 1543156291414
        },
        {
            "id": "5bd31a89e828860007cc9810",
            "group_id": "5919759152faff000545b18c",
            "user_id": "5a2e547a46e0fb00053adfc2",
            "content": {
                "start_timestamp": 1537967595630,
                "end_timestamp": 1540559595630,
                "measurements": [
                    {
                        "id": "5bd0766e1124bd47d1974a4b",
                        "visible": true
                    },
                    {
                        "id": "5bb5f4d9e2b0930b3657a57c",
                        "visible": true
                    }
                ]
            },
            "status": "COMPLETE",
            "trigger": "PERIOD_DAYS_PASSED_30",
            "tags": [
                "not_sent"
            ],
            "status_updated_timestamp": 1545127396954,
            "creation_timestamp": 1540561545640,
            "update_timestamp": 1545127396954
        },
        {
            "id": "5bb235c08970110006cebf23",
            "creator_id": "5a2e547a46e0fb00053adfc2",
            "group_id": "5919759152faff000545b18c",
            "user_id": "5a2e547a46e0fb00053adfc2",
            "content": {
                "start_timestamp": 1535813815911,
                "end_timestamp": 1538405815911
            },
            "status": "COMPLETE",
            "trigger": "MANUAL",
            "tags": [
                "not_sent"
            ],
            "share": {
                "hash": "dbfe970ce6f7a26b88829cb426e896a9e91f6ac0",
                "creation_timestamp": 1538477697487
            },
            "status_updated_timestamp": 1540291283308,
            "creation_timestamp": 1538405824344,
            "update_timestamp": 1540291283308
        },
        {
            "id": "5bb1f6398970110006cebf21",
            "creator_id": "5a2e547a46e0fb00053adfc2",
            "group_id": "5919759152faff000545b18c",
            "user_id": "5a2e547a46e0fb00053adfc2",
            "content": {
                "start_timestamp": 1535797540457,
                "end_timestamp": 1538389540457
            },
            "status": "COMPLETE",
            "trigger": "MANUAL",
            "tags": [
                "not_sent"
            ],
            "share": {
                "hash": "cd335c749bda079406bfc9c95f2c856369b3c052",
                "creation_timestamp": 1538477533308
            },
            "status_updated_timestamp": 1540291246981,
            "creation_timestamp": 1538389561544,
            "update_timestamp": 1540291246981
        },
        {
            "id": "5bab87ea8970110006cebcde",
            "group_id": "5919759152faff000545b18c",
            "user_id": "5a2e547a46e0fb00053adfc2",
            "content": {
                "start_timestamp": 1535375595630,
                "end_timestamp": 1537967595630,
                "measurements": [
                    {
                        "id": "5ba6856a5599f28d1dcce22b",
                        "visible": true
                    },
                    {
                        "id": "5b97d40121559987acfcb869",
                        "visible": true
                    },
                    {
                        "id": "5b8c2ad753aaa05217b6ae6c",
                        "visible": true
                    }
                ]
            },
            "status": "COMPLETE",
            "trigger": "PERIOD_DAYS_PASSED_30",
            "tags": [
                "not_sent"
            ],
            "status_updated_timestamp": 1540287449719,
            "creation_timestamp": 1537968106659,
            "update_timestamp": 1540287449719
        },
        {
            "id": "5b83fd1c46e0fb0005738334",
            "group_id": "5919759152faff000545b18c",
            "user_id": "5a2e547a46e0fb00053adfc2",
            "content": {
                "start_timestamp": 1532783595630,
                "end_timestamp": 1535375595630,
                "measurements": [
                    {
                        "id": "5b65d05430fb89d5e674d101",
                        "visible": true
                    },
                    {
                        "id": "5b63740530fb894ab77492cf",
                        "visible": true
                    }
                ]
            },
            "status": "COMPLETE",
            "trigger": "PERIOD_DAYS_PASSED_30",
            "tags": [
                "not_sent"
            ],
            "status_updated_timestamp": 1540287219328,
            "creation_timestamp": 1535376668579,
            "update_timestamp": 1540287219328
        },
        {
            "id": "5b716e2046e0fb000573831a",
            "group_id": "5919759152faff000545b18c",
            "user_id": "5a2e547a46e0fb00053adfc2",
            "content": {
                "start_timestamp": 1530191595630,
                "end_timestamp": 1532783595630
            },
            "status": "COMPLETE",
            "trigger": "PERIOD_DAYS_PASSED_30",
            "tags": [
                "not_sent"
            ],
            "status_updated_timestamp": 1540287105514,
            "creation_timestamp": 1534160416628,
            "update_timestamp": 1540287105514
        },
        {
            "id": "5b34ebfa46e0fb00057382f2",
            "group_id": "5919759152faff000545b18c",
            "user_id": "5a2e547a46e0fb00053adfc2",
            "content": {
                "start_timestamp": 1527599595630,
                "end_timestamp": 1530191595630
            },
            "status": "COMPLETE",
            "trigger": "PERIOD_DAYS_PASSED_30",
            "tags": [
                "not_sent"
            ],
            "status_updated_timestamp": 1540286984442,
            "creation_timestamp": 1530194938634,
            "update_timestamp": 1540286984442
        },
        {
            "id": "5ae5cc1ec9e77c000533a3e2",
            "group_id": "5919759152faff000545b18c",
            "user_id": "5a2e547a46e0fb00053adfc2",
            "content": {
                "start_timestamp": 1522415595630,
                "end_timestamp": 1525007595630,
                "measurements": [
                    {
                        "id": "5abe90f94cedfd00056ea6ad",
                        "visible": true
                    },
                    {
                        "id": "5abe769e4cedfd00056ea6ac",
                        "visible": true
                    }
                ]
            },
            "status": "COMPLETE",
            "trigger": "PERIOD_DAYS_PASSED_30",
            "tags": [
                "not_sent"
            ],
            "status_updated_timestamp": 1540286639636,
            "creation_timestamp": 1525009438704,
            "update_timestamp": 1540286639636
        }
    ]
}
```

{% endtab %}
{% endtabs %}

To render a PDF version of the periodic report:

## Render periodic report

<mark style="color:blue;">`GET`</mark> `https://api.fibricheck.com/reports/v1/{reportId}/pdf?language={language}&time_zone={timeZone}`

This API call renders a PDF version of a periodic report.

#### Path Parameters

| Name                                       | Type   | Description                                              |
| ------------------------------------------ | ------ | -------------------------------------------------------- |
| reportId<mark style="color:red;">\*</mark> | String | The report for which a PDF version needs to be generated |

#### Query Parameters

| Name     | Type   | Description                                         |
| -------- | ------ | --------------------------------------------------- |
| language | String | The language in which te report should be generated |
| timeZone | String | The timezone in which te report should be generated |

{% tabs %}
{% tab title="200: OK PDF Report" %}

```javascript
{
    // Response
}
```

{% endtab %}
{% endtabs %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.fibricheck.com/introduction/reports.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
