This page assumes you know how to:
- Edit queries in the Power Query editor and read and adapt M code, including custom functions.
- Work with REST APIs in general: HTTP methods, JSON request and response bodies, and cursor-based pagination.
- Use the CDF API: find the endpoint you need, build its request body and filters, and follow its pagination rules. See the Cognite API introduction.
Power BI template
To get started quickly, you can use a Power BI template file (.pbit) that includes all the utility functions and helper functions documented on this page. It also includes additional functions for incremental refresh. The template saves you from manually copying and pasting each function into your Power BI report.
Download Power BI template
Download a zip file that contains the template file (
TemplateCDF.pbit), with all utility functions pre-configured.What’s included
The template contains the following components:
Getting started with the template
1
Download and open the template
Download
TemplateCDF.zip, extract TemplateCDF.pbit, and open it in Power BI Desktop. Opening a template creates a new report and doesn’t modify the template file.2
Enter connection parameters
When prompted, enter your CDF project name in
CogniteProject and your organization in CogniteOrganization. You can also set RangeStart and RangeEnd, or keep the default values. To change the values later, select Transform Data > Edit parameters.3
Sign in
When prompted, sign in with your organizational account to authenticate with CDF.
4
Start building
Select Transform Data to open the Power Query editor and view the functions. Create your queries using the pre-configured functions, or use them as a reference alongside the documentation on this page.
5
Save the report
Save your work as a Power BI report file (
.pbix).Use the template as a companion file and refer to the connector functions, this page, and the incremental refresh documentation for detailed explanations, parameters, and usage examples.
Utility functions
Convert timestamps from/to epoch
CDF resource types expect and return timestamps using milliseconds since the Unix epoch. Power Query doesn’t have methods to automatically parse this format to adatetimezone type to represent timezone-aware timestamps. CDF data models represent timestamps using the ISO 8601 format for primitive fields.
Use the functions below to convert between a datetimezone variable and milliseconds since the Unix epoch and from a datetimezone variable to text in ISO 8601 format.
ConvertMsToUtcDateTime returns a plain datetime that represents UTC, rather than a zone-aware value. Use it when the result is compared against the RangeStart and RangeEnd parameters used for incremental refresh. For the opposite direction, use ConvertDateTimeToMs.
ConvertDateTimeZoneToMs
ConvertDateTimeZoneToMs
Convert datetimezone to milliseconds since epoch
ConvertMsToDateTimeZone
ConvertMsToDateTimeZone
Convert milliseconds since epoch to datetimezone
ConvertMsToUtcDateTime
ConvertMsToUtcDateTime
Convert milliseconds since epoch to a UTC datetime
ConvertDateTimeZoneToIso
ConvertDateTimeZoneToIso
Convert DateTimeZone to ISO 8601 text representation
Add function
To add a new function in Power Query, select Get Data > Blank Query and write your function or copy one of the functions below.Time deltas
It’s common to define start and end timestamps based on time deltas. The values are updated when the semantic model is refreshed. In the example below,EndTime is the current time, and StartTime is 7 days before EndTime. The query returns StartTime and EndTime in UTC. You can adapt it to use different time deltas.
Time deltas
Common GET request
When you fetch data from CDF using theGetCDF function from the CDF REST API connector for Power BI, you must use query parameters to pass on filters to select which data to fetch.
The example below adds the space, includeGlobal, and limit query parameters of the /models/views endpoint to the URL to filter data on the server side.
List the views in the cdf_cdm space
Common POST request
When you fetch data from CDF with thePostCDF function, you must write a request body to select which data to fetch. The function accepts a text representation of the JSON body, but you can also write the body using a Power Query record data type and then convert it to a JSON text data type before passing the value to the PostCDF function.
List all data modeling instances for a view using the DMS API
") with another set of double-quote characters:
ListInstancesDMS, you can use it in a new query by entering the field values in Power Query or by writing a new query:
GraphQL requests
When you fetch data from CDF using theGraphQL function, you must write a GraphQL request to select which data to fetch from a specific data model. The function expects you to specify the external ID of the space, the external ID of the data model, the version of the data model, the GraphQL query to run, and optionally a set of variables to be used in the query.
The query below uses the GraphQL syntax and passes the variables as JSON texts. Using variables in the query makes it easier to parameterize and use with external values.
List all work orders with an end date greater than a specific date
#(lf) represents a line-break character. In the example above, the query was pasted into the text area field in Power BI and the variables were passed as JSON text. Notice how Power BI added the line breaks to the original query and expressed it as a single-line text variable.
Alternatively, you can write the query directly as a multi-line text variable. You can define the variables as Power Query records and convert them to JSON text before passing them to the GraphQL function. For example, see how the ConvertDateTimeZoneToIso function converts a datetimezone variable to a text representation of the ISO 8601 format and then passes it as a variable to the query.
Advanced examples
Depending on the shape of the Cognite API response, you may need additional Power Query transformations to fetch and transform the data. Copy and adapt the examples below to fit your business needs.Fetch instances from the DMS query endpoint with the PostCDF function
The Power Query function below retrieves and processes data modeling instances for a DMS query. It paginates through the response, extracts the instances, and expands the nested data.
QueryDMS function
QueryDMS function
Fetch instances from the DMS query endpoint with PostCDF
equipment result follows the asset direct relation on CogniteEquipment back to the selected assets. You can’t traverse a list of direct relations inwards, such as assets on CogniteActivity. To go from activities to their assets, query the activities and use direction = "outwards".
Fetch time series datapoints with the PostCDF function
The Power Query function below retrieves and processes raw or aggregated datapoints for a numeric, string, or state time series within a time range. It converts local timezone inputs to UTC for the CDF API requests, supports multiple aggregates and custom granularity, and handles data pagination. The function then converts the returned UTC timestamps back to the local timezone, expands the nested API response, and outputs a well-formatted table with properly typed columns. It also includes local timestamps.
Identify a time series by its instance ID, which is its space and externalId, written as [ space = "my_space", externalId = "my_time_series" ]. The output includes the instanceId.space and instanceId.externalId columns, so you can tell the time series apart in a combined table.
Use the optional fillLimit parameter to enable server-side gap filling for aggregate queries. The function sends fill = [limit = fillLimit] on the query item in every request, including subsequent pages.
Output columns by time series type
The function reads the time series type from the response and returns these value columns. Each row also hastimestamp, type, instanceId.space, and instanceId.externalId, plus unitExternalId if the time series has a unit.
CDF returns an error for an aggregate marked as not available, and for
targetUnit or targetUnitSystem on a string or state time series.
CDF accepts stateCount, stateDuration, and stateTransitions together with other aggregates, but this function can’t combine them in one table, because it returns one row per state for them. Request them in a separate call from other aggregates. A state with nothing to report in a time range has no row for that time range. For how CDF calculates these aggregates, see state aggregates.
A time range with no datapoints returns the same columns with no rows, so you can use the function with incremental refresh. If a time series doesn’t exist, the function fails with a Time series not found error from CDF. RetrieveDataPointsMultipleTs fails the same way if any time series in the list doesn’t exist. The error doesn’t name the time series, so check the space and externalId of each one.
RetrieveDataPoints function
RetrieveDataPoints function
Fetch time series datapoints with PostCDF
RetrieveDataPointsMultipleTs function
RetrieveDataPointsMultipleTs function
Fetch multiple time series datapoints with PostCDF
"4h" as the last parameter:
RetrieveDataPointsMultipleTs to iterate over a list of time series instance IDs with daily aggregates and a two-day fill limit:
Fetch records from a stream with the PostCDF function
The Power Query function below fetches records through a record view. It reads the stream ID, property names, and data types from the view, then returns a table with a column for each selected property.
You can use this function with all stream types, including for incremental refresh. It selects records by lastUpdatedTime, the time CDF last created, updated, or deleted the record. For mutable streams, see Immutable and mutable streams before you set up refresh.
Create the
PostCDF query from the connector and add ConvertMsToUtcDateTime from this page, plus ConvertDateTimeToMs and EnforceSchema from Utility functions.
RetrieveRecords function
RetrieveRecords function
Fetch records from a stream with PostCDF
usedFor is not record or that do not reference exactly one stream. An empty window (startUtc = endUtc) validates the view and returns the typed schema without reading records. A reversed window is an error.
To use the function:
RangeStart and RangeEnd, and keep the row filter so Power BI recognizes the date limits:
properties parameter to fetch only the properties your report needs. To check whether the first refresh fits, see Plan the first refresh.
Immutable and mutable streams
A record is identified by itsspace and externalId. How you handle the loaded rows depends on the stream type:
A row with
status = "deleted" is a tombstone. It can still contain the record’s previous property values, so always check status.
For a mutable stream with a full refresh, each record appears once, so removing the tombstones in Power Query is enough:
Exclude deleted records (full refresh)
space and externalId as the key and status as the deletion field.
RetrieveRecords reads from the sync endpoint, which returns tombstones for at least three days after a record is deleted. Other record endpoints usually stop returning the deleted record within a few seconds. See Delete records in the Records API reference. Keep the reload period in the policy shorter than three days, with time for failed refreshes to retry.
Learn more: Microsoft Power Query documentation