HeadSpin Documentation
Documentation

Session Annotation API

Session Name and Description

Fetch the name and description associated with a session

Assign a name and description for a session

Reset the name and description of a session to the default values

Fetch the name and description associated with a session

Route Method
/v0/sessions/{session_id}/description GET

Example


curl https://<your_api_token>@api-dev.headspin.io/v0/sessions/{session_id}/description

Response


{
    "name": "HeadSpin Session",
    "description": "HeadSpin Performance Dashboard/Analytics."
}

Assign a name and description for a session

If the session already has a name and description, this route will overwrite the current name and description.

Route Method
/v0/sessions/{session_id}/description POST

Example


curl -X POST https://<your_api_token>@api-dev.headspin.io/v0/sessions/{session_id}/description -d '{"name": "My name", "description": "My description."}'

Response

  • A <code class="dcode">HTTP 200 OK</code> response if the request is successful
  • A <code class="dcode">HTTP 404</code> Not Found response if the request fails. Make sure that the session id in your request is valid.

Reset the name and description of a session to the default values

Route Method
/v0/sessions/{session_id}/description DELETE

Example


curl -X DELETE https://<your_api_token>@api-dev.headspin.io/v0/sessions/{session_id}/description

Response

  • A <code class="dcode">HTTP 200 OK</code> response if the request is successful
  • A <code class="dcode">HTTP 404</code> Not Found response if the request fails. Make sure that the session id in your request is valid.

Session Tags

Get all tags for a session

Create a tag for a session

Delete all tags in a session

Get all tags for a session

Route Method
/v0/sessions/tags/{session_id} GET

Example


curl https://<your_api_token>@api-dev.headspin.io/v0/sessions/tags/{session_id}

Response

The response is a list of key: value pairs for all the tags applied to that session. For example:


[
    {"sessiontype": "demo"},
    {"tag_key": "test"}
]

Create a tag for a session

Route Method
/v0/sessions/tags/{session_id} POST

Request Body

The request body may be a JSON object of the following form:


{
    "tags": [
        {"<tag_key>": "<tag_value>"},
        {"<tag_key>": "<tag_value>"}
    ]
}

or a flat JSON array of key, value tags:


[
    {"<tag_key>": "<tag_value>"},
    {"<tag_key>": "<tag_value>"}
]

Example


curl -X POST https://<your_api_token>@api-dev.headspin.io/v0/sessions/tags/{session_id} -d '{"tags": [{"demo": "tag"}, {"hello": "world"}]}'

Response

  • <code class="dcode">HTTP 200 OK</code> response if the request was successful and tags are added to the session.
  • <code class="dcode">HTTP 400 OK</code> response if the request body was invalid. Make sure you have a correct request body.
  • <code class="dcode">HTTP 404</code> if the session can't be found. Make sure you have the correct session id.

Delete all tags in a session

Route Method
/v0/sessions/tags/{session_id} DELETE

Example


curl -X DELETE https://<your_api_token>@api-dev.headspin.io/v0/sessions/tags/{session_id}

Response

  • <code class="dcode">HTTP 200 OK</code> response if the request was successful. All tags in the session will be deleted.
  • <code class="dcode">HTTP 404</code> if the session can't be found. Make sure you have the correct session id.

Session Labels

Label object

Time formatting

Available session label types

Add labels to a session

Get labels associated with a session

Get a specific label

Get all labels associated with a label group

Update an existing label

Delete an existing label

Retrieve keyframe screenshots

Apply spatial filtering on video analyses

Copy a label to a target session

Label object

The Session Anotation API allows you create and manipulate labels for segments of a capture session. Labels are objects with the following properties:

Session Label Object Property Description
label_id A UUID that uniquely identifies the label.
session_id (optional) The label group UUID that the label is associated with.
label_group_id The session UUID that the label is associated with.
name A string name for a label.
start_time The start time relative to session start. See note on session time formatting.
end_time (optional) The end time relative to session start. See note on session time formatting.
ts_start The absolute (UNIX) start time. See note on session time formatting.
ts_end (optional) The absolute (UNIX) end time. See note on session time formatting.
label_type (optional, default "user") A string that is the type of the label. The label type determines how HeadSpin responds to the label. See the note on available session label types, below.
category (optional) A string that is the category of the label. The label category is converted to lower case.
data (optional) Any useful JSON-serializable content associated with this label.
pinned (optional, default false) A boolean flag indicating whether the label is pinned to the session or not. Pinned labels are shown by default when viewing a session, under the right panel's Details section.
Pinned labels cannot be deleted.
video_box (optional) Coordinates of bounding boxes provided as nested arrays in the format [[x0, y0, x1, y1], ...]. See the note on applying spatial filtering in video analyses

Time formatting

Segments are specified by start and end timestamps. Relative (to session start), absolute (UNIX), or an appropriate combination of both timestamps (e.g., <code class="dcode">ts_start</code> and <code class="dcode">end_time</code>) can be provided in a JSON object.

Relative timestamps (time since session start)


{
    "start_time": "<time>",  // required
    "end_time": "[<time>]"  // optional
}

The <code class="dcode">&lt;time></code> parameter must be provided either as integer milliseconds or as a string in  <code class="dcode">"HH:MM:SS.milliseconds"</code> format. For example, the  <code class="dcode">&lt;time></code> parameter representing 1.5 seconds after session start may be represented in integer milliseconds as  <code class="dcode">1500</code>, and in  <code class="dcode">"HH:MM:SS.milliseconds"</code> as  <code class="dcode">"00:00:01.5"</code> or  <code class="dcode">"1.5"</code>. The end_time key is optional. If no  <code class="dcode">end_time</code> is provided, the label will be considered instantaneous at the corresponding  <code class="dcode">start_time</code>.

Absolute timestamps (UNIX time)


{
    "ts_start": "<time>",  // required
    "ts_end": "[<time>]"  // optional
}

The <code class="dcode">&lt;time></code> parameter must be provided as seconds. The ts_end key is optional and if not provided, the label will be considered instantaneous at the corresponding <code class="dcode">ts_start</code>.

Available session label types

Users can currently create labels of the following session label types:

Free-form annotations:

  • <code class="dcode">"user"</code>: The default <code class="dcode">"label_type"</code> for a free-form Session Annotation.

User Feedback label types (see our documentation on Providing Feedback on HeadSpin Performance Sessions):

Label Type Description
needs-improvement Feedback that an existing solution is insufficient or inadequate and needs to be improved to be useful.
report-an-error Feedback that the existing solution is broken or unusable.
suggestion A tip, hint, or friendly request regarding ways HeadSpin could better meet your needs.

Analysis label types (see our Session Analysis API Documentation).

Label Type Description
audio-activity-request Runs the audio activity analysis inside the label's timespan.
audio-match-request Runs the audio match analysis inside the label's timespan.
image-match-request Runs the image match analysis inside the label's timespan.
loading-animation-request Runs the loading animation issue analysis inside the label's timespan.
ocr-request Runs the OCR (Optical Character Recognition) analysis inside the label's timespan.
page-load-request Runs the visual page load time analysis inside the label's timespan.
time-series-request Runs the time series data analysis inside the label's timespan.
video-content Runs the video quality analyses inside the label's timespan.

Add labels to a session

A single label or multiple labels can be added at a time.

Route Method
/v0/sessions/{session_id}/label/add POST

Request Body

The body should be a JSON label object.

An example body for adding a single label:


{
    "name": "a helpful name",
    "category": "an optional category for the label",
    "start_time": "10.5",
    "end_time": "1:20.1",
    "data": {"optional": "data"},
    "pinned": true
}

An example body for adding multiple labels at once:


{
    "labels": [
        {"name": "test label 1", "start_time": 5000},
        {"name": "test label 2", "start_time": 10000}
    ]
}

Example: Add a single label


curl -X POST https://<your_api_token>@api-dev.headspin.io/v0/sessions/{session_id}/label/add -d '{"name": "a helpful name", "category": "an optional category for the label", "start_time": "10.5", "end_time": "1:20.1", "data": {"optional": "data"}, "pinned": true}'

Response

If the request is successful, a <code class="dcode">HTTP 200 OK</code> response is returned with the label ID as a JSON object:


{"label_id": "bf1434cf-99f4-11e9-b9f7-f21898a483e5"}

Example: Add multiple labels at a time


curl -X POST https://<your_api_token>@api-dev.headspin.io/v0/sessions/{session_id}/label/add -d '{"labels": [{"name": "test label 1", "start_time": 5000}, {"name": "test label 2", "start_time": 10000}]}'

Response

If the request is successful, a <code class="dcode">HTTP 200 OK</code> response is returned with the label IDs as a JSON object:


{"label_ids": ["be9fcccc-5b88-11eb-8aae-b5c31a9b9aee", "be9fcccd-5b88-11eb-8aae-b5c31a9b9aee"]}

Get labels associated with a session

Route Method
/v0/sessions/{session_id}/label/list?label_type={label_type}&category={category}&name={name} GET

Example: Get all labels in a session


curl https://<your_api_token>@api-dev.headspin.io/v0/sessions/{session_id}/label/list

Response

The response is a JSON object with the <code class="dcode">labels</code> key, and it contains a list of label objects. For example:


{
    "labels": [
        {
            "label_id": "bf1434cf-99f4-11e9-b9f7-f21898a483e5",
            "session_id": "4867b234-92c3-11e9-9362-02e56c2f74c2",
            "label_type": "user",
            "category": "an optional category for the label",
            "name": "a helpful name",
            "start_time": 10500,
            "end_time": 80100,
            "ts_start": 1585162717.054,
            "ts_end": 1585162786.654,
            "data": {"optional": "data"},
            "pinned": true
        }
    ]
}

Example: Get labels in a session that have <code class="dcode">"page load"</code> as <code class="dcode">category</code> and <code class="dcode">"load Screen A"</code> and <code class="dcode">name</code>


curl --get https://<your_api_token>@api-dev.headspin.io/v0/sessions/{session_id}/label/list --data-urlencode category="page load" --data-urlencode name="load Screen A"

Response


{
    "labels": [
        {
            "label_id": "916a4e97-8769-11eb-94ef-06c4c57ba6cd",
            "session_id": "6d05aaa1-8377-11eb-8fb7-067dc7f9db8c",
            "label_group_id": "916a4e98-8769-11eb-94ef-06c4c57ba6cd",
            "label_type": "page-load-request",
            "category": "page load",
            "name": "load Screen A",
            "start_time": 831,
            "end_time": 4488,
            "ts_start": 1615583458.077,
            "ts_end": 1615583461.734,
            "data": null,
            "video_box": null,
            "pinned": false
        },
        {
            "label_id": "9336c862-8769-11eb-9156-0a7763e7e383",
            "session_id": "6d05aaa1-8377-11eb-8fb7-067dc7f9db8c",
            "label_group_id": "916a4e98-8769-11eb-94ef-06c4c57ba6cd",
            "label_type": "page-load-result",
            "category": "page load",
            "name": "load Screen A",
            "start_time": 3480,
            "end_time": 3880,
            "ts_start": 1615583460.726,
            "ts_end": 1615583461.126,
            "data": {"end_sensitivity": 0.975, "start_sensitivity": 0.835},
            "video_box": null,
            "pinned": false
        }
    ]
}

Get a specific label

Route Method
/v0/sessions/label/{label_id} GET

Example


curl https://<your_api_token>@api-dev.headspin.io/v0/sessions/label/bf1434cf-99f4-11e9-b9f7-f21898a483e5

Response

A successful requests receives a JSON response with the specified label for the given session.


{
    "label_id": "bf1434cf-99f4-11e9-b9f7-f21898a483e5",
    "session_id": "4867b234-92c3-11e9-9362-02e56c2f74c2",
    "name": "a helpful name",
    "category": "an optional category for the label",
    "start_time": 10500,
    "end_time": 80100,
    "ts_start": 1585162717.054,
    "ts_end": 1585162786.654,
    "data": {"optional": "data"},
    "pinned": true
}

Get all labels associated with a label group

Labels that are "linked" have the same <code class="dcode">label_group_id</code> assigned to them, which can be used to fetch the group of labels. For example, a <code class="dcode">page-load-request</code> label and a <code class="dcode">page-load-result</code> label can be "linked", because the <code class="dcode">page-load-request</code> label drives the Visual Page Load Analysis which then creates the <code class="dcode">page-load-result</code> label.

Route Method
/v0/sessions/label/group/{label_group_id} GET

Example


curl https://<your_api_token>@api-dev.headspin.io/v0/sessions/label/group/{label_group_id}

Response

The response is a JSON object with the <code class="dcode">labels</code> key, and it contains a list of label objects.


{"labels":
    [
        {
            "label_id": "6c4f23de-04b0-4550-b6e4-3fbfaf005e89",
            "label_group_id": "1c8501bc-4ca0-4aa3-b73d-10dc5bddba0b",
            "label_type": "page-load-request",
            "session_id": "446c0272-e329-11ea-b51a-bf4d9c36b3f2",
            "name": "test",
            "category": "page load",
            "start_time": 14254,
            "end_time": 28509,
            "ts_start": 1597076919.267,
            "ts_end": 1597076933.522,
            "data": null,
            "pinned": false,
        },
        {
            "label_id": "6aec3050-e32b-11ea-b51a-bf4d9c36b3f2",
            "label_group_id": "1c8501bc-4ca0-4aa3-b73d-10dc5bddba0b",
            "label_type": "page-load-result",
            "session_id": "446c0272-e329-11ea-b51a-bf4d9c36b3f2",
            "name": "test",
            "category": "page load",
            "start_time": 15760,
            "end_time": 27760,
            "ts_start": 1597076920.773,
            "ts_end": 1597076932.773,
            "data": {"end_sensitivity": 0.975, "start_sensitivity": 0.835},
            "pinned": false,
        }
    ]
}

Update an existing label

Route Method
/v0/sessions/label/{label_id} PATCH

Request Body

The body should be a JSON with the fields of the label to update.


{
    "name": "new name",
    "category": "new category",
    "start_time": "1:00.7",
    "end_time": "1:30.5",
    "data": {"optional": "data", "more": "data"},
    "pinned": false
}

Example


curl -X PATCH https://<your_api_token>@api-dev.headspin.io/v0/sessions/label/bf1434cf-99f4-11e9-b9f7-f21898a483e5 -d '{"name": "new name", "category": "new category", "start_time": "1:00.7", "end_time": "1:30.5", "data": {"optional": "data", "more": "data"}, "pinned": false}'

Response

  • <code class="dcode">{"status": "OK", "status_code": 200}</code> if the label is updated successfully.
  • <code class="dcode">{"status": "Label not found.", "status_code": 404}</code> if the label is not found. Check that the label ID is correct.

Delete an existing label

Route Method
/v0/sessions/label/{label_id} DELETE

Example


curl -X DELETE https://<your_api_token>@api-dev.headspin.io/v0/sessions/label/bf1434cf-99f4-11e9-b9f7-f21898a483e5

Response

  • <code class="dcode">{"status": "OK", "status_code": 200}</code> if the label is deleted successfully.
  • <code class="dcode">{"status": "Label not found.", "status_code": 404}</code> if the label is not found. Check that the label ID is correct.

Retrieve keyframe screenshots

Keyframes are JPEG images corresponding to the start and end of a Session Label time interval. These routes allow you to download the corresponding screenshots.

Route Method
/v0/sessions/label/{label_id}/keyframe/start GET
/v0/sessions/label/{label_id}/keyframe/end GET

Example

We use the <code class="dcode">-o</code> option to specify the location and name for the downloaded screenshot.


curl https://<your_api_token>@api-dev.headspin.io/v0/sessions/label/bf1434cf-99f4-11e9-b9f7-f21898a483e5/keyframe/start -o start-screenshot.jpeg

Response

  • <code class="dcode">A HTTP 200 OK</code> response if the request is successful. The file is saved as specified by the <code class="dcode">-o</code> option.
  • <code class="dcode">{"status": "Label not found.", "status_code": 404}</code> if the label is not found. Check that the label ID is correct.

Apply spatial filtering on video analyses

For video analyses that are driven by session labels, you can instruct where on the frames the analyses should run by specifying the <code class="dcode">"video_box"</code> field in the request labels. <code class="dcode">"video_box"</code> should be provided as nested arrays in the format <code class="dcode">[[x0, y0, x1, y1], ...]</code> where <code class="dcode">x0, y0, x1</code>, and <code class="dcode">y1</code> are the coordinates of the bounding boxes on the video frames. The origin, <code class="dcode">(0, 0)</code>, is placed at the upper left corner of a video frame. For example, <code class="dcode">[[0, 0, 100, 200]]</code> specifies a rectangle on the frame that can be drawn with points <code class="dcode">(0, 0)</code> (at the upper left corner) and <code class="dcode">(100, 200)</code> (100 pixels to the right and 200 pixels below from <code class="dcode">(0, 0)</code>). Note that if the width and height of the session video are 450 and 800, respectively, <code class="dcode">[[0, 0, 450, 850]]</code> specifies the entire frame.

Shown below are the available video analyses and the label types for which specifying <code class="dcode">"video_box"</code> is meaningful:

Analysis Label Type Number of bounding boxes allowed
image match "image-match-request" 1
label copy "user" 1
loading animation "loading-animation-request" >= 1
OCR "ocr-request" 1
page load "page-load-request" 1
video quality "video-content" 1

You can get the dimensions of the session video to help with selecting the coordinates for the desired bounding boxes. Once you have added the labels with video_box specified, you can check what the filtered frames look like by retrieving the screenshot of the labels.

Copy a label to a target session

Copy a reference label to a target session using a visual match algorithm.

Route Method
/v0/sessions/{target session_id}/label/{label_id}/copy POST

The image match algorithm will align the start and end keyframes of the reference label with the video in the target session and apply the copy if the match score exceeds the configured threshold.

The match algorithm will generate a match score ranging from <code class="dcode">0</code> to <code class="dcode">1</code> that represents how visually similar the reference frame is to frames in the target session video. Separate match scores are provided for the start and end keyframes if the reference label is not an instantaneous label. The sensitivity of the match algorithm can be tuned by adjusting the <code class="dcode">match_score_threshold</code>. If needed, a different threshold can be used for matching the end keyframe by setting the <code class="dcode">end_match_score_threshold</code>. A match score threshold of <code class="dcode">0</code> will match any frame and a threshold of <code class="dcode">1</code> will only match an identical frame.

If you wish to apply spatial filtering when copying a label so that only a certain spatial region of the frames will be visually matched, then use a label that has the desired bounding box specified in the <code class="dcode">"video_box"</code> field. You can either specify the <code class="dcode">"video_box"</code> field when adding a label or update an existing label to populate the <code class="dcode">"video_box"</code> field.

Request Body

This route allows an optional body with the following arguments:

argument description example
>match_score_threshold (Optional) The minimum match score necessary to successfully copy a label. Applies to matching both the start and end keyframes. 0.95 (default)
end_match_score_threshold (Optional) The minimum match score necessary for matching the end keyframe. This is useful if different thresholds are desired for matching the start and end keyframes. 0.95 (default)
return_first_end_match (Optional) Whether to return the first frame that meets the match score threshold when matching the end keyframe. By default, this is set to false and hence the last frame that meets the threshold is returned. false (default)

Example

An example for copying a reference label with <code class="dcode">label_id</code> <code class="dcode">bf1434cf-99f4-11e9-b9f7-f21898a483e5</code> to a target session with <code class="dcode">session_id</code> <code class="dcode">b0d36a38-a296-11e9-8169-f21898a483e5</code> is shown below:


curl -X POST https://<your_api_token>@api-dev.headspin.io/v0/sessions/b0d36a38-a296-11e9-8169-f21898a483e5/label/bf1434cf-99f4-11e9-b9f7-f21898a483e5/copy -d '{"match_score_threshold": 0.98}'

Response

If a match is found, an example return value is:


{
    "status": "success",
    "match_score_threshold": 0.98,
    "start_match_score": 0.9855,
    "end_match_score": 0.9831,
    "reference_session_id": "4867b234-92c3-11e9-9362-02e56c2f74c2",
    "copied_label": {
        "label_id": "69467e5c-d031-11ea-b434-bf4d9c36b3f2",
        "label_group_id": "be9b9b2d-7ca9-455d-b64e-5070e861bd3b",
        "label_type": "copied-label",
        "session_id": "b0d36a38-a296-11e9-8169-f21898a483e5",
        "name": "a helpful name",
        "category": "an optional category for the label",
        "start_time": 11500,
        "end_time": 81600,
        "ts_start": 1585164178.21,
        "ts_end": 1585164248.31,
        "data": {"optional": "data"},
        "pinned": false
    }
}

If no match is found:


{
    "status": "error",
    "match_score_threshold": 0.98,
    "reference_session_id": "4867b234-92c3-11e9-9362-02e56c2f74c2",
    "error_msg": "No match found for the start reference frame at the current match score threshold. The highest match score is 0.9022 with the frame at 10760 ms."
}

If a match was found for the start keyframe but not the end keyframe:


{
    "status": "error",
    "match_score_threshold": 0.98,
    "start_match_score": 0.9837,
    "start_time": 11500,
    "reference_session_id": "4867b234-92c3-11e9-9362-02e56c2f74c2",
    "error_msg": "No match found for the end reference frame at the current match score threshold. The highest match score is 0.7855 with the frame at 307200 ms."
}

Get the reference and copied labels associated with a label group

The reference label and its copied labels have the same label_group_id. You can fetch all the labels that share the same label group ID.