Browse the docs

Integrations

Power BI export

Connect Power BI to an organization's results with a read-only API key and the Power Query snippets in Settings, and see what each dataset contains.

Plans: EnterpriseView as Markdown
On this page

The Power BI export is a read-only data feed that Power BI pulls from on each refresh. It serves these datasets as JSON: totals per simulation, totals per coach, daily activity, one row per learner attempt, and one row per transcript message. An owner or admin of an organization workspace on the Enterprise plan sets it up by creating an API key and pasting a ready-made Power Query snippet into Power BI.

Before you start

  • The organization's plan must be Enterprise. devlin.ai can also turn the export on for an individual organization. On any other plan the panel shows a Power BI export card with a View plans button in place of the controls.
  • You must be an owner or admin of the organization. Members cannot open the organization's Integrations section. See Members, roles, invitations and the activity log.
  • The controls are in an organization's settings only. The Integrations page of a personal workspace has no Power BI panel. See Personal and organization workspaces.
  • A key gives whoever holds it read access to the organization's results, including what learners wrote and any learner identity that was collected. Treat it like a password.
  • You need Power BI Desktop to paste the snippet into, and the Power BI service if you want scheduled refresh.

Steps

Create a key:

  1. Make the organization your active workspace (Settings → Workspaces lists your workspaces and switches to the one you pick), then open Integrations in the settings sidebar.
  2. Under API keys, type a name for the key that says what will use it. The name can be up to 100 characters.
  3. Select Create key.
  4. A banner shows the full key with a copy button. Copy it and store it somewhere safe before you dismiss the banner. The key is shown this one time only. devlin.ai does not keep a readable copy, so it cannot be shown again or recovered.

An organization can have up to 5 active keys. When that many exist, creating another fails with "Limit of 5 active keys reached. Revoke one first."

Connect Power BI, following the instructions under Connect Power BI in the same panel:

  1. Under Connect Power BI, select a dataset: simulations, coaches, activity, attempts or transcripts. The snippet below the buttons changes to match. Copy it with the copy button on the snippet.
  2. In Power BI Desktop, the panel directs you to Get Data, then Blank Query, then Advanced Editor. Paste the snippet there.
  3. In the snippet, replace YOUR_API_KEY with the key you copied.
  4. If Power BI asks how to connect, choose Anonymous. The key inside the query is what authenticates the request.
  5. Optional: the snippet's StartDate line sets the earliest data to pull and starts at 2020-01-01. Set a later date to pull less history.
  6. Repeat for each dataset you want, one query per dataset.
  7. Schedule refresh in the Power BI service.

Revoke a key:

  1. In the API keys list, find the key. Each entry shows the name, the first characters of the key (keys start with dvlk_), the date it was created, and the date it was last used or "never used".
  2. Select Revoke, then confirm with Revoke key in the Revoke this key? dialog.

Creating and revoking a key are both recorded in the organization's activity log with the key's name. See Members, roles, invitations and the activity log.

A revoked key stops working immediately and leaves the list. Keys do not expire, and a key cannot be edited or regenerated. A key belongs to the organization, not to the person who created it: it keeps working after that person leaves the organization or changes role, until an owner or admin revokes it. To rotate a key, create a new one, update the queries in Power BI, then revoke the old one.

Result

Each query loads one table. The snippet requests the dataset page by page until the feed reports no further page, then combines the pages. When a dataset has no rows for the range, the query still returns an empty table with the dataset's columns, so later steps in your model keep working.

Every refresh pulls the whole range again, from StartDate to the moment of the refresh.

The feed is read-only. Nothing in Power BI can change the workspace.

What the datasets leave out

Session counts, attempt rows and transcript rows leave out:

  • Designer test runs.
  • Sessions where the learner never sent a message.
  • The replaced part of a voice session that dropped and was resumed. The resumed session is the one that counts.

Evaluation counts and scores leave out evaluations that belong to a designer test run or to the replaced part of a resumed voice session.

The credits columns of simulations, coaches and activity are counted from the workspace's usage charges, not from the sessions, so they are not reduced by these rules.

No dataset contains evaluator submissions or results. To get them, see Exporting results, transcripts and evaluations.

The attempts and transcripts datasets cover simulations only. Coaches appear as totals in coaches and as a daily count in activity.

Datasets and columns

Times are ISO timestamps. A column described as empty holds a null value.

simulations

One row per simulation in the workspace, including simulations with no activity in the range. Counts cover the range the query asks for.

Column Meaning
simulation_id The simulation's ID. Join to attempts and transcripts on this column.
name The simulation's name.
status The simulation's status.
sessions Learner sessions that started in the range.
completions Those sessions that have ended.
unique_learners Distinct learners among those sessions, counted by learner ID, or by browser session where there is no learner ID.
evals Evaluations created in the range. This follows the evaluation's time, not the session's start time.
pass_rate The share of scored evaluations that passed, as a whole percent. Empty when no evaluation in the range was scored. Feedback-only evaluations are not counted as scored.
avg_score The average score percent of scored evaluations. Empty when none was scored.
credits Credits charged to the simulation in the range.
last_activity When the most recent counted session in the range started. Empty when there was none.

coaches

One row per coach in the workspace, including coaches with no activity in the range.

Column Meaning
coach_id The coach's ID.
name The coach's name.
status The coach's status.
sessions Coach sessions that started in the range.
unique_learners Distinct learners among those sessions, counted the same way as for simulations.
credits Credits charged to the coach in the range.
last_activity When the most recent counted session in the range started. Empty when there was none.

activity

One row per day for the whole workspace. A day with no sessions, evaluations or credit usage has no row. This dataset comes back in a single response.

Column Meaning
bucket_start The start of the day.
sessions Simulation sessions that started that day.
completions Those sessions that have ended.
coach_sessions Coach sessions that started that day.
evals Evaluations created that day.
pass_count Evaluations created that day that passed.
avg_score The average score percent of that day's scored evaluations. Empty when none was scored.
credits Credits the workspace used that day, counted from its usage charges, not only learner sessions.

attempts

One row per learner attempt at a simulation, oldest first. The range applies to when the attempt started.

Column Meaning
conversation_id The attempt's ID. Join to transcripts on this column.
simulation_id The simulation's ID.
simulation_name The simulation's name.
session_id The learner's browser session.
learner_id The learner ID stored with the attempt.
learner_identifier The identifier the learner entered or the course passed in. Empty if none was collected, or after the workspace's retention window cleared it.
learner_attributes The attempt's learner identity field values as one piece of JSON text. Empty if none were collected, or after the workspace's retention window cleared them. Parse it in Power Query to get one column per field.
started_at When the attempt started.
ended_at When the attempt ended. Empty if it has not ended.
mode text or voice.
completed True when the attempt has ended.
credits Credits charged to the attempt.
eval_pass Whether the attempt's most recent evaluation passed. Empty when there is no evaluation or it was feedback-only.
eval_score The score percent of the most recent evaluation, rounded to a whole number. Empty when there is no evaluation or it was feedback-only.

eval_pass and eval_score are the AI's result. A reviewer's adjustment from human review is not applied.

The organization's learner identity visibility setting does not hide the learner identity columns in this feed. In a workspace with a retention window, learner_id, learner_identifier and learner_attributes are emptied on attempts older than the window. Only owners and admins can create a key, and they always see learner identity. See Collecting learner identity.

transcripts

One row per stored message in a simulation attempt, oldest first. The range applies to when the message was sent. To get the learner, the simulation's name, the mode or the evaluation for a message, join to attempts on conversation_id.

Column Meaning
message_id The message's ID.
conversation_id The attempt the message belongs to.
simulation_id The simulation's ID.
role user for the learner, assistant for the character.
content The text of the message.
created_at When the message was sent.

A workspace's retention window deletes old messages, so they stop appearing in transcripts while the attempt can still be counted elsewhere. See Data privacy and retention.

Date range

Each request takes an optional from and to, both ISO dates. The snippet always sends from with the value of StartDate and leaves to out, which means up to now. A request with no from gets the 365 days before to, so if you write your own query, send from or older rows will drop out of your model as they age past that window.

Limits

  • Each key can make 60 requests per minute. A request above that gets Too many requests with a Retry-After header that says how many seconds to wait. Each page of a dataset is one request.
  • The feed sets no row limit of its own. simulations, coaches, attempts and transcripts arrive as more pages, and activity arrives in one response.

If the plan changes

The feed checks the organization's plan on every request. When the organization is no longer on a plan that includes the export, requests are refused straight away and scheduled refreshes fail. The keys are not revoked. The panel lists them under Existing API keys so you can revoke them, and you cannot create new ones. If the organization returns to a plan that includes the export, keys that were not revoked work again.

Errors a refresh can show

The feed answers a failed request with a short JSON error, which Power BI reports as a failed web request.

Status and error What it means
401 Unauthorized The request has no key, the key is mistyped, or it is not a key this feed knows. Check that YOUR_API_KEY was replaced with the whole key.
403 Unauthorized The key was revoked, or the organization's plan no longer includes the export.
429 Too many requests The key passed its per-minute limit, or too many requests with a bad key came from the same network address. Wait and refresh again.
400 Unknown dataset The dataset name in the URL is not one of the datasets listed above.
400 from must be before to StartDate (or a from you added) is later than to, or later than now when to is left out.
400 from and to must be valid ISO dates StartDate (or a from or to you added) is not a valid date.
400 Invalid cursor The page marker was altered. Use the snippet as copied.
500 Internal server error The request failed on the devlin.ai side. Refresh again.

In the settings panel, "Could not load Power BI settings. Refresh to try again." means the key list did not load. Reload the page.