HeadSpin Documentation
Documentation

Basic Device API

API Reference

List all devices

List all devices matched by selector

List all device information keys

Get remote control URLs for devices

Get remote control URLs for devices matched by selector

Get all devices' automatic testing configuration

Lock a device

Lock a device matched by selector

List all devices locked by the requesting user

Unlock a device

Force unlock

Unlock a device matched by device selector

Get device notes

Get device notes

List all devices

Route Method
/v0/devices GET

curl -H "Authorization: Bearer <your_api_token>" https://api-dev.headspin.io/v0/devices 

Optional Parameters

  • <code class="dcode">/v0/devices?selector=&lt;url-encoded-json&gt;</code>, the selector query parameter can be used as an alternative to path arguments used to filter devices.

Example

  • to filter devices based on Device SKU matching "Galaxy S22", construct a JSON that looks like <code class="dcode">{"device_skus": "Galaxy S22"}</code> and URL encode it <code class="dcode">%7B%22device_skus%22%3A%20%22Galaxy%20S22%22%7D</code> to pass it as an argument to the query parameter.

curl -X GET -H "Authorization: Bearer <your_api_token>" "https://api-dev.headspin.io/v0/devices?selector=%7B%22device_skus%22%3A%20%22Galaxy%20S22%22%7D" 

Response

A JSON object in the form of <code class="dcode">{"devices": [...]}</code> that has a list of device objects. Each device object has the keys listed as in the <code class="dcode">/v0/devices/keys</code> route.

An example:


{
  "devices": [
    {
      "status": 3,
      "hostname": "proxy-us-mv-1.headspin.io",
      "phone_imei": 357656089117376,
      "display_secure": true,
      "network_roaming": false,
      "phone_iccid": null,
      "network_connected": true,
      "device_type": "android",
      "operator": ",",
      "serial": "2124d0e6",
      "device_note": "",
      "city": "Mountain View",
      "is_companion_device": false,
      "carriers": [],
      "abi": "armeabi-v7a",
      "geos": [
        "Mountain View, US"
      ],
      "battery_voltage": 4.304,
      "os_version": "7.1.1",
      "hsbt_device": null,
      "avbox_info": {},
    ...
    ...
    }]
...
}

If the device is using bluetooth audio there will be a key with the paired bluetooth device name:


"hsbt_device": "hsbta-150-0"

If the device is part of an A/V box setup there will be extra information about that setup. Assume there is a device with id 1234 set up as device-under-test and it has a camera device with id 5678. The two devices would be listed as:


    "serial": "1234",
    "hostname": "proxy-us-mv-1.headspin.io",
    ...
    "avbox_info": {
        "usage": "device_under_test",
        "screen": null,
        "devices": ["5678@proxy-us-mv-1.headspin.io"]
    }
},
{
    "serial": "5678",
    "hostname": "proxy-us-mv-1.headspin.io",
    ...
    "avbox_info": {
        "usage": "camera_device",
        "screen": "front",
        "devices": ["1234@proxy-us-mv-1.headspin.io"]
    }
}

For each device usage indicates how the device is used inside the A/V box, it can be "device_under_test", "camera" or "audio". The devices list contains the address of related devices (so for the device-under-test that is the camera, and the other way around) and screen is the screen name used in the avbox API.

List all devices matched by selector

Route Method
/v0/devices/{device_selector}/information GET

Devices can now be filtered using Device Selectors

Example


curl -X GET -H "Authorization: Bearer <your_api_token>" https://api-dev.headspin.io/v0/devices/device_type:ios+os_version:>=15.4+hostname:{hostname}/information 

Response


{
  "devices": [
    {
      "phone_number": "+1-925-895-4401",
      "battery_voltage": null,
      "phone_imei": 353056105273242,
      "display_ydpi": null,
      "display_secure": false,
      "network_roaming": false,
      "phone_iccid": "89312530000035015900",
      ...
      ...
      "device_type": "ios",
      "os_version": "15.4",
      "hostname": "proxy-us-nyc-4.headspin.io"

List all device information keys

The response from /v0/devices contains a list of devices and their information in JSON format. This route lists all the keys each device object contains.

Route Method
/v0/devices/keys GET

Example


curl -H "Authorization: Bearer <your_api_token>" https://api-dev.headspin.io/v0/devices/keys 

Response

A JSON object in the form of {"keys": [...]} that has a list of keys.


{
  "keys": [
    "hostname",
    "device_id",
    "serial",
    "phone_imei",
    "status",
    "operator",
    "phone_iccid",
    "phone_number",
    "phone_network",
    "network_type",
    "network_subtype",
    "network_connected",
    "network_failover",
    "network_roaming",
    "manufacturer",
    "model",
    "os_version",
    "abi",
    "sdk",
    "display_width",
    "display_height",
    "display_rotation",
    "display_secure",
    "display_size",
    "display_xdpi",
    "display_ydpi",
    "battery_health",
    "battery_source",
    "battery_status",
    "battery_level",
    "battery_temp",
    "battery_voltage",
    "notes",
    "timestamp",
    "removed",
    "device_type",
    "device_subtype",
    "device_state",
    "owner_email",
    "carriers",
    "city",
    "country",
    "device_note",
    "device_skus",
    "geos",
    "is_companion_device"
  ]
}

Get all devices' automatic testing configuration

This route provides the device configuration for automated test frameworks.

Route Method
/v0/devices/automation-config GET

Example


curl -H "Authorization: Bearer <your_api_token>" https://api-dev.headspin.io/v0/devices/automation-config 

Response

The response is a JSON object that has an entry for each available device. The key for each entry is a device address ({device_id}@{host}) and contains information to configure automatic testing.

driver_url refers to an Appium WebDriver server, and capabilities refers to default Appium capabilities.

Example


{
  "025ed06ec3da2602@proxy-us-mvo-1.headspin.io": {
    "device_location": {
      "city": "mvo",
      "carrier": "Google Fi",
      "country_readable": "US",
      "city_readable": "Mountain View",
      "lat": 37.3860517,
      "country": "us",
      "lon": -122.0838511
    },
    "lock_url": "https://us-mvo.headspin.io:7200/v0/{api_token}/lock",
    "working_dir": "/home/pbox/appium_tests/025ed06ec3da2602",
    "capabilities": {
      "udid": "025ed06ec3da2602",
      "deviceName": "025ed06ec3da2602",
      "automationName": "UiAutomator2",
      "autoAcceptsAlerts": "true",
      "platformName": "Android"
    },
    "host": "proxy-us-mvo-1.headspin.io",
    "unlock_url": "https://us-mvo.headspin.io:7200/v0/{api_token}/unlock",
    "driver_url": "https://us-mvo.headspin.io:7200/v0/{api_token}/wd/hub",
    "device_carrier": {
      "network_subtype": "",
      "network_connected": true,
      "network_type": "WIFI",
      "phone_network": "LTE",
      "carrier": "Google Fi"
    },
    "os": "android",
    "control_url": "https://us-mvo.headspin.io:7100"
  },
...
}

Automation Configurations can also be filtered using Device Selectors. Please refer to API for Automation Configuration for more details.

Get remote control URLs for devices

Retrieve remote control URLs for devices that can be directly loaded into a browser to be able to view the device and interact it.

Route Method
/v0/device-url GET

Optional Parameters

Name Value Meaning
limit positive integer Only retrieve at most this many devices and urls
selector selector Filter devices by the given selector
filter "online" or "all" Retrieve only online devices, or all devices
responsetype "json", "csv", or "text" Output format. "text" contains just the url. "json" is the default

Output formats

The json format has the following structure


{"devices": [{"device_id": <device id>, "web_url": <url>}, ...]}

The value of the devices key is a list of dictionaries that each contain two keys, device_id and web_url. The device_id is an identifier for the device, and the web_url is a URL that can be used in a web browser to access the device.

The csv format is similar to json but formatted as a series of lines with the values separated by a comma


device_id,web_url
<deviceid1>, <url1>
<deviceid2>, <url2>
...

The text format returns just the url, separated by a comma for multiple devices. For a single device just that url would be returned.


<url>

or for multiple devices


<url1>, <url2>, ...

Sample output for json


{"devices": [
  {"device_id": "079ed2e100d3847e",
   "web_url": "https://ui.headspin.io/remotecontrol/control?d=us-mvo-1:079ed2e100d3847e"
  },
  {"device_id": "37defe46431700f1e14d27bf9ad1532b5374ae22",
   "web_url": "https://ui.headspin.io/remotecontrol/control?d=us-mvo-2:37defe46431700f1e14d27bf9ad1532b5374ae22"
  }
]}

Example

Json output


curl -H "Authorization: Bearer <your_api_token>" https://api-dev.headspin.io/v0/device-url 

Text output


curl -H "Authorization: Bearer <your_api_token>" https://api-dev.headspin.io/v0/device-url?responsetype=text 

Get url for a single device


curl -H "Authorization: Bearer <your_api_token>" https://api-dev.headspin.io/v0/device-url?responsetype=text&limit=1 

Get remote control URLs for devices matched by selector

Route Method
/v0/device-url/{device_selector}/info GET

Device URLs can also be filtered using Device Selectors


curl -X GET -H "Authorization: Bearer <your_api_token>" https://api-dev.headspin.io/v0/device-url/device_type:ios+os_version:>=15.4+hostname:{hostname}/info 

This is a sample response


{"devices": [
  {"device_id": "079ed2e100d3847e",
   "web_url": "https://ui.headspin.io/remotecontrol/control?d=us-mvo-1:079ed2e100d3847e"
  },
  {"device_id": "37defe46431700f1e14d27bf9ad1532b5374ae22",
   "web_url": "https://ui.headspin.io/remotecontrol/control?d=us-mvo-2:37defe46431700f1e14d27bf9ad1532b5374ae22"
  }
]}

Lock a device

Lock a device matching the specified criteria.

Route Method
/v0/devices/lock POST

Optional Parameters

  • <code class="dcode">/v0/devices/lock?automation</code>: Lock the device as the team's automation user.
  • <code class="dcode">/v0/devices/lock?idleTimeout={timeout seconds}</code>: Unlock automatically if the device is inactive for <code class="dcode">timeout seconds</code>.

Request Body

  • If the request body is empty, an arbitrary device will be locked.
  • If the request body contains a selector as a JSON object, a device matching the criteria in the selectors will be locked. For example: <code class="dcode">'{"hostname":"proxy-us-mvo-2.headspin.io", "model": "iPhone 6"}'</code>

Example

To lock an arbitrary device:


curl -X POST -H "Authorization: Bearer <your_api_token>" https://api-dev.headspin.io/v0/devices/lock 

To lock an arbitrary device as your team's automation user:


curl -X POST -H "Authorization: Bearer <your_api_token>" https://api-dev.headspin.io/v0/devices/lock?automation 

To lock a device matching a selector:


curl -X POST -H "Authorization: Bearer <your_api_token>" https://api-dev.headspin.io/v0/devices/lock --data '{"hostname":"{hostname}"}' -H "Content-Type: application/json" 

Response

A JSON object:

  • <code class="dcode">{"status": "Locked device at &lt;hostname> with device_id &lt;device_id>", "status_code": 200, "serial": "&lt;device_serial>", "hostname": "&lt;hostname>", "device_id": "&lt;device_id>"}</code> if a device was locked successfully.
  • <code class="dcode">{"status": "Failed to parse selector json. No JSON object could be decoded", "status_code": 400}</code> if the request body cannot be parsed as a JSON object. Double check to make sure that there's no syntax error.
  • <code class="dcode">{"status": "Invalid keys: &lt;list of invalid keys>", "status_code": 400}</code> if one or more keys in the selector JSON object is not a supported keys. To see available keys, use the /v0/devices/keys route.
  • <code class="dcode">{"status": "No devices match.", "status_code": 403}</code> if there is no device matching the selector.

Lock a device matched by selector

Route Method
/v0/devices/{device_selector}/lock POST

curl -X POST -H "Authorization: Bearer <your_api_token>" https://api-dev.headspin.io/v0/devices/hostname:{hostname}/lock 

Response

A JSON object:

  • <code class="dcode">{"status": "Locked device at &lt;hostname> with device_id &lt;device_id>", "status_code": 200, "serial": "&lt;device_serial>", "hostname": "&lt;hostname>", "device_id": "&lt;device_id>"}</code> if a device was locked successfully.
  • <code class="dcode">{"status": "Failed to parse selector json. No JSON object could be decoded", "status_code": 400}</code> if the request body cannot be parsed as a JSON object. Double check to make sure that there's no syntax error.
  • <code class="dcode">{"status": "Invalid keys: &lt;list of invalid keys>", "status_code": 400}</code> if one or more keys in the selector JSON object is not a supported keys. To see available keys, use the <code class="dcode">/v0/devices/keys</code> route.
  • <code class="dcode">{"status": "No devices match.", "status_code": 403}</code> if there is no device matching the selector.

List all devices locked by the requesting user

Route Method
/v0/devices/lock GET

Example


curl -H "Authorization: Bearer <your_api_token>" https://api-dev.headspin.io/v0/devices/lock 

Response

A JSON object in the form of <code class="dcode">{"devices": [...]}</code> that has a list of device objects, one for each device currently locked by the requesting user. Each device objects have the keys listed as in the <code class="dcode">/v0/devices/keys</code> route.

For example see /v0/devices.

Unlock a device

Unlock all devices matching the specified criteria, if they are locked by the requesting user. Does not unlock devices locked with the team's automation user.

Route Method
/v0/devices/unlock POST

Request Body

  • If the request body is empty, all devices locked by the requesting user will be unlocked.
  • If the request body contains a selector as a JSON object, all devices matching the criteria in the selectors will be unlocked. For example: '{"manufacturer":"samsung"}'

Example

To unlock all devices in use by the requesting user:


curl -X POST -H "Authorization: Bearer <your_api_token>" https://api-dev.headspin.io/v0/devices/unlock 

To unlock a device matching a selector:


curl -X POST -H "Authorization: Bearer <your_api_token>" https://api-dev.headspin.io/v0/devices/unlock --data '{"hostname":"{hostname}"}' -H "Content-Type: application/json" 

Response

If there's no device matching the selector, the response is a JSON object:

  • <code class="dcode">{"status": "No devices match.", "status_code": 403}</code>

If there is at lease one matching device, or no selector given, the response is a JSON object <code class="dcode">{statuses}</code> whose value is a list of devices, one for each device matching the selector. Each item in the list can have one of these values:

  • <code class="dcode">{"message": "Device unlocked.", "hostname": &lt;hostname>, "serial": &lt;device_serial>, "success": true, "device_id": &lt;device_id>}</code> if the device was locked to the requesting user, and now unlocked.
  • <code class="dcode">{"message": "Device is already unlocked.", "hostname": &lt;hostname>, "serial": &lt;device_serial>, "success": false, "device_id": &lt;device_id>}</code> if the device was already unlocked.
  • <code class="dcode">{"message": "Device in use by another user.", "hostname": &lt;hostname>, "serial": &lt;device_serial>, "success": false, "device_id": &lt;device_id>}</code> if the device is currently locked by another user.

Example:


{
  "statuses": [
    {
      "message": "Device unlocked.",
      "hostname": "proxy-us-mv-1.headspin.io",
      "serial": "2124d0e6",
      "success": true,
      "device_id": "357656089117376"
    },
    {
      "message": "Device unlocked.",
      "hostname": "proxy-us-mv-1.headspin.io",
      "serial": "289ad974",
      "success": true,
      "device_id": "354169084305379"
    },
    {
      "message": "Device is already unlocked.",
      "hostname": "proxy-us-mv-1.headspin.io",
      "serial": "988a1b343136594c4b",
      "success": false,
      "device_id": "35280509176124"
    },
    {
      "message": "Device is already unlocked.",
      "hostname": "proxy-us-mvo-1.headspin.io",
      "serial": "2ad32118",
      "success": false,
      "device_id": "99000582746458"
    },
    {
      "message": "Device in use by another user.",
      "hostname": "proxy-us-mvo-3.headspin.io",
      "serial": "42009571e4cca4fb",
      "success": false,
      "device_id": "352002091722801"
    }
  ]
}

Force unlock

Unlock all devices which match the specified criteria and are accessible by the requesting user, even if locked by another team member.

Route Method
/v0/devices/force-unlock POST

This uses the same request body and returns the same response as the unlock route.

Example

To unlock all accessible devices:


curl -X POST -H "Authorization: Bearer <your_api_token>" https://api-dev.headspin.io/v0/devices/force-unlock

To unlock devices matching a selector:


curl -X POST -H "Authorization: Bearer <your_api_token>" https://api-dev.headspin.io/v0/devices/force-unlock --data '{"hostname":"{hostname}"}' -H "Content-Type: application/json"

Unlock a device matched by device selector


Route Method
/v0/devices/{device_selector}/unlock POST

Response

If there's no device matching the selector, the response is a JSON object:

  • <code class="dcode">{"status": "No devices match.", "status_code": 403}</code>

If there is at lease one matching device, or no selector given, the response is a JSON object <code class="dcode">{statuses}</code> whose value is a list of devices, one for each device matching the selector. Each item in the list can have one of these values:

  • <code class="dcode">{"message": "Device unlocked.", "hostname": &lt;hostname>, "serial": &lt;device_serial>, "success": true, "device_id": &lt;device_id>}</code> if the device was locked to the requesting user, and now unlocked.
  • <code class="dcode">{"message": "Device is already unlocked.", "hostname": &lt;hostname>, "serial": &lt;device_serial>, "success": false, "device_id": &lt;device_id>}</code> if the device was already unlocked.
  • <code class="dcode">{"message": "Device in use by another user.", "hostname": &lt;hostname>, "serial": &lt;device_serial>, "success": false, "device_id": &lt;device_id>}</code> if the device is currently locked by another user.

Example:


{
  "statuses": [
    {
      "message": "Device unlocked.",
      "hostname": "proxy-us-mv-1.headspin.io",
      "serial": "2124d0e6",
      "success": true,
      "device_id": "357656089117376"
    },
    {
      "message": "Device unlocked.",
      "hostname": "proxy-us-mv-1.headspin.io",
      "serial": "289ad974",
      "success": true,
      "device_id": "354169084305379"
    },
    {
      "message": "Device is already unlocked.",
      "hostname": "proxy-us-mv-1.headspin.io",
      "serial": "988a1b343136594c4b",
      "success": false,
      "device_id": "35280509176124"
    },
    {
      "message": "Device is already unlocked.",
      "hostname": "proxy-us-mvo-1.headspin.io",
      "serial": "2ad32118",
      "success": false,
      "device_id": "99000582746458"
    },
    {
      "message": "Device in use by another user.",
      "hostname": "proxy-us-mvo-3.headspin.io",
      "serial": "42009571e4cca4fb",
      "success": false,
      "device_id": "352002091722801"
    }
  ]
}

Get device notes

Route Method
/v0/devices/{device_selector}/notes GET

Response

  • <code class="dcode">{"device_notes": {"&lt;device_address>": "<notes>", ...}}</code> if device notes were retrieved successfully.

Update device notes

Route Method
/v0/devices/notes PATCH

Request Body

  • Please provide a JSON object in the request body containing the keys, <code class="dcode">device_note</code> and <code class="dcode">device_addresses</code>, like in the example below.

curl -X PATCH -H "Authorization: Bearer <your_api_token>" https://api-dev.headspin.io/v0/devices/notes -d '{"device_note": "sample note", "device_addresses": ["5678@proxy-us-mv-1.headspin.io", "1234@proxy-us-mv-1.headspin.io"]}' 

Response

  • <code class="dcode">{"status": "success", "status_code": 200}</code> if device notes were updated successfully.
  • <code class="dcode">{"status": <error message>, "status_node: 4XX}</code> if there was an error.