The Performance Monitoring API can be used to programmatically work with User Flows. See Performance Monitoring UI for a high-level description of HeadSpin Performance Monitoring and User Flows.
In this document we cover the routes that read and modify User Flows.
Performance events tie sessions to user flows along with their measurements. A performance event can also exist in isolation without a session. If a session is removed from a user flow, the underlying performance event is deleted and all custom measurements will no longer be associated with that session. Session capture measurements will persist, however. If a performance event is removed from a user flow, those measurements will be lost.
description: If user flow already exists, this will not be updated.
created_time: UNIX timestamp in seconds.
400: Missing or invalid arguments.
Example
curl -X PUT -H "Authorization: Bearer <your_api_token>" https://api-dev.headspin.io/v0/userflows \
--data '{"name": "New User Flow", "description": "A new user flow for testing"}'
# Output
{
"user_flow_id": "8da4f275-d09f-4151-9237-9743194b0843",
"name": "New User Flow",
"description": "A new user flow for testing",
"created_time": 1653077875.205
}
Deleting a User Flow
Route
Method
/v0/userflows/{user_flow_id}
DELETE
Response
<code class="dcode">200</code>: User flow successfully deleted.
<code class="dcode">404</code>: User flow does not exist.
<code class="dcode">session_id={session_id}</code>: Select this session's measurements. <code class="dcode">session_id=</code> can be specified multiple times to filter on several sessions.
<code class="dcode">key={name}</code>: Select measurements with this key name. <code class="dcode">key=</code> can be specified multiple times to filter on several key names.
<code class="dcode">start_time={ISO|Unix timestamp}</code>: Inclusive lower bound for measurements' event time in either ISO formatted string or UNIX timestamp number.
<code class="dcode">end_time={ISO|Unix timestamp}</code>: Inclusive upper bound for measurements' event time in either ISO formatted string or UNIX timestamp number.
<code class="dcode">limit={num}</code>: Limit the number of measurements to <code class="dcode">num</code>.
<code class="dcode">offset={num}</code>: Start the selection at an offset by num, to be used with <code class="dcode">limit=</code>.
<code class="dcode">format={csv|json}</code>: Format of the response, either CSV or JSON. Default is JSON.
<code class="dcode">status={passed|failed|not_set|excluded}</code>: Filter measurements on the status of their sessions. Can be specified multiple times. If <code class="dcode">status</code> is omitted, then these statuses are implied: <code class="dcode">passed</code>, <code class="dcode">failed</code>, and <code class="dcode">not_set</code>.
# Get measurements from only sessions that are PASSED
curl -H "Authorization: Bearer <your_api_token>" "https://api-dev.headspin.io/v0/userflows/{user_flow_id}/measurements?status=passed"
# Get measurements from sessions that are either PASSED or UNSET
curl -H "Authorization: Bearer <your_api_token>" "https://api-dev.headspin.io/v0/userflows/{user_flow_id}/measurements?status=passed&status=not_set"
Filtering by Measurement Name
# For key "All Issues Impact Time"
curl --get -H "Authorization: Bearer <your_api_token>" https://api-dev.headspin.io/v0/userflows/{user_id}/measurements \
--data-urlencode "key=All Issues Impact Time"
Filtering on Event Time
<code class="dcode">start_time</code> and <code class="dcode">end_time</code> can be given as an ISO formatted datetime or UNIX timestamp.
# The following are equivalent for `start_time` 2022-03-30 16:48:22
curl --get -H "Authorization: Bearer <your_api_token>" https://api-dev.headspin.io/v0/userflows/{user_flow_id}/measurements \
--data-urlencode "start_time=2022-03-30 16:48:22"
curl -H "Authorization: Bearer <your_api_token>" "https://api-dev.headspin.io/v0/userflows/{user_flow_id}/measurements?start_time=1648673302.0"
In the event of no measurements returned when requesting CSV, the response will be empty with a status of 204.
Paging Through Measurements
If a user flow has a large number of measurements, it may be useful to query the measurements in chunks specified by the <code class="dcode">limit=</code> and <code class="dcode">offset=</code> parameters. While no page info is returned, one can assume that if the result set is empty, no more results lie beyond it. The following Python snippet demonstrates requesting measurements 10 at a time until done.
Note: If new sessions and measurements that match the query are added while paging through, the offset will be invalidated and results may be duplicated or missing.
{
"session_id": "..." // Session UUID ID, required
"status": "..." // One of "Passed", "Failed", "Excluded", optional
"status_message": "..." // Optional status message
}
Response
200: Updated session info.
user_flow_id
perf_event_id
status
status_message
host
device_id
event_time: ISO format timestamp.
400:
Missing argument (session_id).
Invalid arguments (bad session_id).
Invalid status (Must be one of "Passed", "Failed", "Excluded").
Session already belongs to another user flow.
404: Session or user flow does not exist.
Note: If a session gets attached to a user flow and its status is set to Passed, Failed, or Excluded, standard tags will be automatically added to the session. For more details on what these standard tags are, see Annotating Your Session: Session Tags.
<code class="dcode">key={name}</code>: Select measurements with this key name. <code class="dcode">key=</code> can be specified multiple times to filter on several key names.
<code class="dcode">limit={num}</code>: Limit the number of measurements to <code class="dcode">num</code>.
<code class="dcode">offset={num}</code>: Start the selection at an offset by num, to be used with <code class="dcode">limit=</code>.
<code class="dcode">format={csv|json}</code>: Format of the response, either CSV or JSON. Default is JSON.
<code class="dcode">404</code>: User flow or session does not exist.
Note: While this does not remove measurements generated through session capture, any custom measurements uploaded will be lost. If the event has no session associated, all measurement data will be lost.
<code class="dcode">key={name}</code>: Select measurements with this key name. <code class="dcode">key=</code> can be specified multiple times to filter on several key names.
<code class="dcoe">limit={num}</code>: Limit the number of measurements to <code class="dcode">num</code>.
<code class="dcode">offset={num}</code>: Start the selection at an offset by <code class="dcode">num</code>, to be used with <code class="dcode">limit=</code>.
<code class="dcode">format={csv|json}</code>: Format of the response, either CSV or JSON. Default is JSON.
Note: If new measurements for this event are added while paging through, the offset will be invalidated and results may be duplicated or missing.
Custom Measurement Data
The expected measurement POST payload for routes <code class="dcode">/v0/userflows/{user_flow_id}/sessions/{session_id}/measurements</code> and <code class="dcode">/v0/userflows/{user_flow_id}/events/{event_id}/measurements</code> is:
The <code class="dcode">data</code> field contains a list of measurements to be added to a session. A measurement is a key/value pair with additional metadata fields <code class="dcode">type</code> and <code class="dcode">units</code>. The type is effectively a category name that can be used to group measurements into categories.
For example, in the Performance Monitoring UI, the measurements dropdown groups measurements by type. In the following screenshot, "HeadSpin Session Metrics" is the <code class="dcode">type</code>, "Average Wait" is the <code class="dcode">key</code>, and "milliseconds" is the <code class="dcode">units</code>:
The <code class="dcode">units</code> field is pure metadata and is not used in analysis.
The <code class="dcode">value</code> field does not have to be numeric. Non-numeric measurements will be ignored by the Performance Monitoring UI when rendering timeseries.
Note: The HeadSpin <code class="dcode">v0</code> API refers to User Flows as <code class="dcode">perftests</code>. In some instances the field <code class="dcode">test_name</code> is used to refer to a User Flow name and <code class="dcode">perf_test_id</code> to refer to the User Flow ID. This discrepancy will be corrected in a future update to the API.
The Performance Monitoring API routes are as follows:
Route
Method
Description
/v0/perftests
GET
Retrieve a list of all user flows
/v0/perftests/{user_flow_id}
GET
Retrieve info about a specific user flow
/v0/perftests/upload
POST
Upload or update measurement data to a user flow
Listing User Flows (Legacy)
curl -H "Authorization: Bearer <your_api_token>" https://api-dev.headspin.io/v0/perftests
# Output:
{
"perf_tests": [
{
"created_time": 1538172182.261,
"perf_test_id": "44a82e55-c36a-11e8-a1a8-00e04c6858ee",
"description": null,
"name": "My User Flow"
},
{
"created_time": 1548213723.6,
"perf_test_id": "0dce9ae5-1ebe-11e9-afbe-06af87227a14",
"description": "A Description",
"name": "Another User Flow"
},
...
]
}
The <code class="dcode">created_time</code> is the time of creation of the User Flow as a unix epoch timestamp in seconds. The <code class="dcode">perf_test_id</code> is the ID of the User Flow, which corresponds to the ID in the UI URL bar when the User Flow is opened. For example if the URL bar is <code class="dcode">https://ui-dev.headspin.io/performance/userflows/44a82e55-c36a-11e8-a1a8-00e04c6858ee the perf_test_id is 44a82e55-c36a-11e8-a1a8-00e04c6858ee</code>.
Reading a Single User Flow (Legacy)
Append the User Flow ID to the above route to narrow in on a single User Flow:
curl -H "Authorization: Bearer <your_api_token>" https://api-dev.headspin.io/v0/perftests/44a82e55-c36a-11e8-a1a8-00e04c6858ee
# Output
{
"created_time": 1538172182.261,
"perf_test_id": "44a82e55-c36a-11e8-a1a8-00e04c6858ee",
"description": null,
"name": "My User Flow"
}
Creating and Updating User Flow Data (Legacy)
<code class="dcode">/v0/perftests/upload</code> is a powerful route which can be used to achieve the following:
Create a new user flow
Attach a session to a user flow
Change the status of a session in a user flow
Upload new measurements to a session in a user flow
Modify existing measurements to a session in a user flow
Subsets of these actions can be performed simulatenously in a single HTTP request.
The POST payload to this route is as follows:
{
"test_name": "...", // User Flow name
"session_id": "...", // Session ID
"status": "...", // One of: "passed", "failed", "excluded"
"data": [ // Measurement data
{
"key": "...", // Measurement name
"value": "...", // Measurement value
"type": "...", // Measurement type/category; Optional
"units": "..." // Measurement units; Optional
},
...
]
}
The <code class="dcode">data</code> field contains a list of measurements to be added to a session. A measurement is a key/value pair with additional metadata fields <code class="dcode">type</code> and <code class="dcode">units</code>. The type is effectively a category name that can be used to group measurements into categories.
For example, in the Performance Monitoring UI, the measurements dropdown groups measurements by type. In the following screenshot, "HeadSpin Session Metrics" is the <code class="dcode">type</code>, "Average Wait" is the <code class="dcode">key</code>, and "milliseconds" is the <code class="dcode">units</code>:
The <code class="dcode">units</code> field is pure metadata and is not used in analysis.
The <code class="dcode">value</code> field does not have to be numeric. Non-numeric measurements will be ignored by the Performance Monitoring UI when rendering timeseries.
Attaching a session to a user flow (Legacy)
To attach a session to user flow, we pass the user flow name in <code class="dcode">test_name</code> and the the session's <code class="dcode">session_id</code>:
curl -X POST -H "Authorization: Bearer <your_api_token>" https://api-dev.headspin.io/v0/perftests/upload \
-d '{"test_name": "My User Flow", "session_id": "7ef6c7ba-6c6d-11e9-be69-a45e60be08cf"}'
Important Note: If the user flow with the given name does not exist, a new user flow with this name will be created, and the session will be attached to it.
Updating the status of a session (Legacy)
To update the status of a session that is already attached to a user flow, we pass the <code class="dcode">session_id</code> and <code class="dcode">status</code>
To add a custom measurement named "My Measurement" with value <code class="dcode">50</code>, we invoke the API as follows:
curl -X POST -H "Authorization: Bearer <your_api_token>" https://api-dev.headspin.io/v0/perftests/upload \
-d '{"session_id": "7ef6c7ba-6c6d-11e9-be69-a45e60be08cf", "data": [{"key": "My Measurement", "value": 50}]}'
Notes:
Many measurements can be added at the same time, by appending to the <code class="dcode">data</code> list.
The <code class="dcode">type</code> and <code class="dcode">units</code> fields can be optionally passed for each measurement.
If a measurement with that name and type already exists, its value will be overwritten with the new value.
Simultaneous updates (Legacy)
The above three update modes (Attaching a session to a user flow, Updating the status on a session, Adding custom measurements) can be performed simulanously, by passing all the fields: <code class="dcode">test_name</code>, <code class="dcode">session_id</code>, <code class="dcode">status</code>, and <code class="dcode">data</code>.
Retrieving KPI Measurements (Verizon)
This route is intended to serve KPI values that are stored as measurements. A single KPI is comprised of three measurements that specify <code class="dcode">time_to_interactive</code>, <code class="dcode">availability</code>, and <code class="dcode">ttfb</code> (time to first byte). For a measurement to appear as part of a KPI, given a key name <code class="dcode">$KEY</code>, there should be measurement with key name <code class="dcode">$KEY_ttfb</code> in the user flow.
Route
Method
/v0/userflows/{user_flow_id}/verizon
GET
Query Parameters
<code class="dcode">session_id={session_id}</code>: Select this session's measurements. <code class="dcode">session_id=</code> can be specified multiple times to filter on several sessions.
<code class="dcode">kpi={name}</code>: Select KPIs with this name. <code class="dcode">kpi=</code> can be specified multiple times to filter on several kpis.
<code class="dcode">start_time={ISO|Unix timestamp}</code>: Inclusive lower bound for measurements' event time in either ISO formatted string or UNIX timestamp number.
<code class="dcode">end_time={ISO|Unix timestamp}</code>: Inclusive upper bound for measurements' event time in either ISO formatted string or UNIX timestamp number.
<code class="dcode">format={csv|json}</code>: Format of the response, either CSV or JSON. Default is JSON.
<code class="dcode">status={passed|failed|not_set|excluded}</code>: Filter measurements on the status of their sessions. Can be specified multiple times. If <code class="dcode">status</code? is omitted, then these statuses are implied: <code class="dcode">passed</code>, <code class="dcode">failed</code>, and <code class="dcode">not_set</code>.
curl -H "Authorization: Bearer <your_api_token>" "https://api-dev.headspin.io/v0/userflows/{user_flow_id}/verizon?format=csv"
# Output
session_id,user_flow_id,user_flow_name,session_start_time,location,kpi,time_to_interactive,availability,ttfb,amID,e2erequestid,digital_ig_session
dece402e-eb9d-11ec-a563-acde48001122,33d76193-77a6-11eb-b372-021b6b7c1650,Another Test User Flow,2022-06-03 11:11:22,Mountain View - US,Verizon Test Key,8999.0,9001.0,9000.0,072f7c50-2785-4c60-8833-359c5cfbc24a,b02b5205-b86c-49d8-bc8e-f37fc32e9e9d-7089536,POW-M-e42a58c2-6b8e-4a2d-ad1e-67759700ca48
...
Filtering on Session Time
To retrieve KPI data for a specific time frame, use the <code class="dcode">start_time=</code> and <code class="dcode">end_time=</code> query parameters. These values can be specified as an ISO format string or UNIX timestamp. All times should be in UTC.
# Get measurements from only sessions that are PASSED
curl -H "Authorization: Bearer <your_api_token>" "https://api-dev.headspin.io/v0/userflows/{user_flow_id}/verizon?status=passed"
# Get measurements from sessions that are either PASSED or UNSET
curl -H "Authorization: Bearer <your_api_token>" "https://api-dev.headspin.io/v0/userflows/{user_flow_id}/verizon?status=passed&status=not_set"
Filtering on KPIs
To filter on KPIs by name (case-sensitive), use the <code class="dcode">kpi=</code> query parameter. Multiple <code class="dcode">kpi=</code> values can be appended to the same request.
# To filter on "Sign In" KPIs in the user flow
curl --get -H "Authorization: Bearer <your_api_token>" https://api-dev.headspin.io/v0/userflows/{user_flow_id}/verizon \
--data-urlencode "format=csv" \
--data-urlencode "kpi=Sign In"
# Output
session_id,user_flow_id,user_flow_name,session_start_time,location,kpi,time_to_interactive,availability,ttfb
520f225e-cd62-11ec-a6c8-f01898f3a82f,573be968-b41e-11ec-921c-0acef5dbfa51,iOS_AAL,2022-05-06 13:31:11,Palo Alto - US,Sign In,1150.0,100.0,117.0
eef81b5e-cd54-11ec-9a48-f01898f3a82f,573be968-b41e-11ec-921c-0acef5dbfa51,iOS_AAL,2022-05-06 11:55:21,Palo Alto - US,Sign In,4167.0,100.0,200.0
898f87dc-cd53-11ec-aec1-f01898f3a82f,573be968-b41e-11ec-921c-0acef5dbfa51,iOS_AAL,2022-05-06 11:45:22,Palo Alto - US,Sign In,4083.0,100.0,200.0
...
When New KPIs Are Added
This endpoint is designed around the convention of given a KPI like "Shop", there will be three measurements with keys <code class="dcode">Shop</code>, <code class="dcode">Shop_Availability</code>, and <code class="dcode">Shop_ttfb</code>. Therefore, if a new KPI is added, for it to resolve correctly it should conform to this.