HeadSpin Documentation
Documentation

Using A/V Box API

A/V Box API

Table of contents

Overview: Available API Routes

This API allows playback and recording of media on an Android device within a HeadSpin A/V Box accessible by your organization.

Method Route Notes
POST /v0/avbox/upload Upload a media file.
POST /v0/audio/upload Upload a wav file to the audio API.
GET /v0/avbox/info Returns information about the media_id.
GET /v0/avbox/download Returns a media file.
GET /v0/audio/{media_id}/download Returns a recorded audio sample in WAV format.
DELETE /v0/avbox/delete Delete an uploaded media file.
GET /v0/avbox/list Fetches all the media_ids and audio_ids in the user's organization (with the option to filter by the tag field).
POST /v0/avbox/prepare Cache media on a host to prepare it for subsequent playback.
POST /v0/avbox/play/start Starts a worker to play a 'prepared' media_id on a device.
GET /v0/avbox/play/status Returns the status of a playback worker.
GET /v0/avbox/play/wait A blocking request that returns the status of a playback worker once it has run to completion.
POST /v0/avbox/play/stop Stops an active playback worker.
GET /v0/avbox/play/workers/ List playback workers currently/recently active for the given device address.
POST /v0/avbox/record/start Starts a worker to record audio from a device and upload it to a central storage repo.
GET /v0/avbox/record/status Returns the status of a recording worker.
GET /v0/avbox/record/wait A blocking request that returns the status of a recording worker once it has run to completion.
POST /v0/avbox/record/stop Stops an active recording worker.
GET /v0/avbox/record/workers/ List recording workers currently/recently active for the given device address.
POST /v0/avbox/picture Display a picture.
POST /v0/avbox/color Display color.

Upload

External media files can be uploaded with the option to add tags. Successful uploads will return a unique <code class="dcode">media_id</code>.

Method Route
POST /v0/avbox/upload?tag&trim_start_threshold&trim_end_threshold

The optional tag parameter will associate a tag with the media file.

The optional start_trim_threshold and end_trim_threshold parameters can be used to remove silence from the start and/or end of the file before uploading. The value should be between 0 and 1 and specifies the relative volume to be considered silence. 0 means only absolute silence is removed, 0.01 means everything not reaching 1% of the maximum volume is removed.

Example


curl --request POST https://api-dev.headspin.io/v0/avbox/upload?tag=helpful-tag&trim_start_threshold=0.001&trim_end_threshold=0.001 --data-binary "@/path/to/your/audio.wav" 

Response


{
    "success": true,
    "media_id": "313f6795-df6d-4ffa-ba86-7b98f07b4a8d"
}
Method Route
POST /v0/audio/upload

For audio files it is also possible to re-use any files uploaded with Headspin's audio API. These will return an "audio_id" instead of a "media_id" which can then be used with /prepare and /play endpoints of the A/V box API as well.

Response


{
    "success": true,
    "audio_id": "313f6795-df6d-4ffa-ba86-7b98f07b4a8d"
}

Media Information

For a given <code class="dcode">media_id</code> or <code class="dcode">audio_id</code>, information and metadata can be requested.

Method Route
GET /v0/avbox/info

The returned information depends on the media type. For WAV audio (format supported by the audio API), additional properties such as sample rate and duration will be returned.

Example


curl -H "Authorization: Bearer <your_api_token>" https://api-dev.headspin.io/v0/avbox/313f6795-df6d-4ffa-ba86-7b98f07b4a8d/info 

Response 1

The id was a <code class="dcode">media_id</code> and the file is a video:


{
    "success": true,
    "media_id": "313f6795-df6d-4ffa-ba86-7b98f07b4a8d",
    "tag": "helpful-tag",
    "ts_created": 1526337362.000,
    "format": "MIME",
    "mime_type": "video/mp4",
    "size": 1000000,
    "channels": null,
    "frames": null,
    "duration": null,
    "samplerate": null
}

Response 2

The id was a <code class="dcode">media_id</code> and the file is WAV audio:


{
    "success": true,
    "media_id": "313f6795-df6d-4ffa-ba86-7b98f07b4a8d",
    "tag": "helpful-tag",
    "ts_created": 1526337362.000,
    "format": "WAV",
    "mime_type": "audio/x-wav",
    "size": 1824032,
    "channels": 2,
    "samplerate": 48000,
    "frames": 456000,
    "duration": 9.500
}

Response 3

The id was an <code class="dcode">audio_id</code>:


{
    "success": true,
    "audio_id": "313f6795-df6d-4ffa-ba86-7b98f07b4a8d",
    "tag": "helpful-tag",
    "ts_created": 1526337362.000,
    "format": "WAV",
    "mime_type": "audio/x-wav",
    "channels": 2,
    "samplerate": 48000,
    "frames": 456000,
    "duration": 9.500,
    "size": 179200
}

Download

The API allows downloading of media files.

Method Route
GET /v0/avbox/download

You can use the <code class="dcode">-O/--remote-name</code> option in cURL in combination with <code class="dcode">-J/--remote-header-name</code> to write to a file with the filename provided in the <code class="dcode">Content-Disposition</code> response header.

Example: Download a file


curl --remote-name --remote-header-name -H "Authorization: Bearer <your_api_token>" https://api-dev.headspin.io/v0/avbox/313f6795-df6d-4ffa-ba86-7b98f07b4a8d/download 

Response

Outputs to file <code class="dcode">313f6795-df6d-4ffa-ba86-7b98f07b4a8d</code>.

Method Route
GET /v0/audio/download

Audio files recorded on an A/V box are available from the audio API just like recordings made with the audio /capture endpoint.

Delete

Delete an uploaded media file for a given <code class="dcode">media_id</code>.

Method Route
DELETE /v0/avbox/delete

Example


curl -X DELETE -H "Authorization: Bearer <your_api_token>" https://api-dev.headspin.io/v0/avbox/313f6795-df6d-4ffa-ba86-7b98f07b4a8d/delete

Response


{
    "success": true
}

List

This API endpoint fetches all the <code class="dcode">media_ids</code> and <code class="dcode">audio_ids</code> (audio files uploaded with Headspin's audio API) that exist in the user's organization. You can optionally filter the results by the value of the <code class="dcode">tag</code> field. The MySQL <code class="dcode">LIKE</code> operator is used for filtering, which means the two wildcards (<code class="dcode">%</code> and <code class="dcode">_</code>) can be used to search for a specified pattern in the <code class="dcode>tag</code> field (if you're unfamiliar with the usage of wildcards, click here to see examples).

Method Route
GET /v0/avbox/list?tag

Example 1: List media ids and audio ids that exactly match "helpful-tag" in the tag field


curl -X GET -H "Authorization: Bearer <your_api_token>" https://api-dev.headspin.io/v0/avbox/list --data-urlencode "tag=%help%"

Response 1


{
    "audio_ids": [
        "9e22786d-f7df-4c4a-b601-384bc2b06ae9",
        "5eca0c4c-f54f-49f6-9d03-64db261b7e23"
    ],
    "media_ids": [
        "06ed3b9c-d0e1-4e61-b36f-b7ce8449ba97",
        "101c335b-c4dc-46ce-aa52-71fa2ca29bf4",
        "15809558-81e9-41ba-b465-91129f97ac1a"
    ],
    "success": true
}

Example 1: List media ids and audio ids that contain "help" in any position in the tag field


curl -X GET https://<your_api_token>@api-dev.headspin.io/v0/avbox/list --data-urlencode "tag=%help%"

Response 2


{
    "audio_ids": [
        "9e22786d-f7df-4c4a-b601-384bc2b06ae9",
        "5eca0c4c-f54f-49f6-9d03-64db261b7e23"
    ],
    "media_ids": [
        "06ed3b9c-d0e1-4e61-b36f-b7ce8449ba97",
        "101c335b-c4dc-46ce-aa52-71fa2ca29bf4",
        "15809558-81e9-41ba-b465-91129f97ac1a"
    ],
    "success": true
}

Prepare

Always call the <code class="dcode">prepare</code> endpoint at the beginning of a test. It will ensure that screen devices in the A/V are turned on and ready for playback and recording.

Additionally, media files need to be cached on the A/V box host in order to play them back. In addition to specifying <code class="dcode">media_ids</code> for files uploaded with the A/V box API, files uploaded to or created with the audio API can be specified as <code class="dcode">audio_ids</code>. (Both can be specified in a single call as well, for example if a test plays both video and audio samples.) A prepare request will block while attempting to cache <code class="dcode">media_ids</code>, and return once caching is complete. The files will be cached for all the screens accessible by the given device. (Which are normally all on the same host but not necessarily the host the device itself is on.) If screens are already locked and files are already cached the request will return immediately.

Method Route
POST /v0/avbox/prepare

Request Body

The request body must be a JSON object with a device_addressor hostname and <code class="dcode">media_ids</code> or <code class="dcode>audio_ids</code> fields, as shown in the following examples:


{
    "device_address": "my_device@host.headspin.io",
    "media_ids": [
        "6fd55663-0aa4-416e-a752-cfab81a13701",
    ]
}

{
    "hostname": "host.headspin.io",
    "audio_ids": [
        "6fd55663-0aa4-416e-a752-cfab81a13701",
        "6c63cccb-5914-414c-96f5-fd9234147102",
        "375051e0-01e6-4dbb-9e4b-017a411ab7c6"
    ]
}

Example


curl --request POST -H "Authorization: Bearer <your_api_token>" https://api-dev.headspin.io/v0/avbox/prepare --data '{"hostname": "host.headspin.io", "audio_ids": ["6fd55663-0aa4-416e-a752-cfab81a13701", "6c63cccb-5914-414c-96f5-fd9234147102", "375051e0-01e6-4dbb-9e4b-017a411ab7c6"]}' 

Response


{
    "success": false,
    "device-host": {
      "media_ids": {
          "6fd55663-0aa4-416e-a752-cfab81a13701": "cached",
          "6c63cccb-5914-414c-96f5-fd9234147102": "cached",
          "375051e0-01e6-4dbb-9e4b-017a411ab7c6": "error"
      }
    }
}

Note that <code class="dcode">success</code> is <code class="dcode">false</code> if any of the <code class="dcode">media_ids</code> or <code class="dcode">audio_ids</code> failed to cache.

Playback

Only prepared media files can be played back on a device via a playback worker running on the host. A successful start request returns a <code class="dcode">worker_id</code> which can be used to poll for status updates or prematurely stop the worker.

Start playback worker

Method Route
POST /v0/avbox/play/start

Request Body

The request body must be a JSON object with the <code class"dcode">device_address</code>, <code class="dcode">media_id/audio_id</code> and <code class="dcode">screen</code> fields, as shown in the following example:


{
    "device_address": "my_device@host.headspin.io",
    "media_id": "6fd55663-0aa4-416e-a752-cfab81a13701",
    "screen": "front"
}
  • device_address has the following structure: device_id@hostname.
    • device_id must be a device on the host and hostname must be in the user's pool.
    • The specified device should always be the DUT (device under test), not an A/V Box peer device such as the CD (camera device) or AD (auxiliary device). The device the audio will be played out from is determined by the screen parameter instead.
  • media_id or audio_id must be made available for the worker on the host with a prepare request in advance.
  • screen specifies which device will be used for the audio playback and usually has a value of "front" or "back", depending on the A/V Box configuration.
    • It refers to the "screen" of the CD or AD which is typically set up either in front of the DUT or in the back of it.
    • As a special case, if the device_address specified is that of the AD or CD instead of the DUT, then the value "self" can be used to request to play the audio on the AD or CD.
  • scale can optionally be used to request a scaling mode of "fit", "zoom" or "fill". Default is "zoom". This is only used for videos and will determine what happens if the video aspect ratio is different from the screen's aspect ratio.
    • zoom will zoom to the center of the video until the entire screen is filled.
    • fit will draw black bars either left/right or above/below the video to make sure the entire video is shown.
    • fill will ignore the aspect ratio and assymetrically stretch the video to exactly fit the screen.
  • offset can be used to start playback at an offset. The time can be given in seconds or as HH:MM:SS.
  • max_duration can be used to stop playback after a given amount of time. The time can have a suffix of "ms", "s", "m" or "h" otherwise seconds are assumed.
  • transform can be used to transform the display region. It consists of 4 coordinate pairs separated by commas. They represent the top left, top right, bottom right and bottom left corners of the screen as a percentage of the actual dimension. The default is "transform":"0/0/100/0/100/100/0/100" which means no transformation is applied. "transform":"0/0/50/0/50/50/0/50" would scale the screen by 50% and keep the video in the upper left corner. This is done in addition to the scale transform - so for example to place the entire video within the 4 corners given by transform ignoring aspect ratio scale should be set to fill.

Example 1

Play a video from start to end.


curl --request POST -H "Authorization: Bearer <your_api_token>" https://api-dev.headspin.io/v0/avbox/play/start --data '{
  "device_address": "my_device@host.headspin.io",
  "media_id": "6fd55663-0aa4-416e-a752-cfab81a13701",
  "screen": "front"}' 

Example 2

Play a video starting at timestamp 12 minutes 34 seconds and play for 3.5 minutes.


curl --request POST -H "Authorization: Bearer <your_api_token>" https://api-dev.headspin.io/v0/avbox/play/start --data '{
  "device_address": "my_device@host.headspin.io",
  "media_id": "6fd55663-0aa4-416e-a752-cfab81a13701",
  "screen": "back",
  "offset": "00:12:34",
  "max_duration": "3.5m"}'

Example 3

Identical to example 2.


curl --request POST -H "Authorization: Bearer <your_api_token>" https://api-dev.headspin.io/v0/avbox/play/start --data '{
  "device_address": "my_device@host.headspin.io",
  "media_id": "6fd55663-0aa4-416e-a752-cfab81a13701",
  "screen": "back",
  "offset": "754",
  "max_duration": "210"}' 

Example 4

Play a video with the bottom side stretched by 20%.


curl --request POST -H "Authorization: Bearer <your_api_token>" https://api-dev.headspin.io/v0/avbox/play/start --data '{
  "device_address": "my_device@host.headspin.io",
  "media_id": "6fd55663-0aa4-416e-a752-cfab81a13701",
  "screen": "front",
  "transform":"0/0/100/0/110/100/-10/100"}'

Response

If the request is successful, a <code class="dcode">worker_id</code> is returned in the response.


{
    "success": true,
    "worker_id": "6c7d6c1b27a147a2af48be263ea9a517"
}

Status of playback worker

The worker can be polled for live status updates. In general, workers can have the following states: <code class="dcode">initializing</code>, <code class="dcode">playing</code>, <code class="dcode">finished</code>, or <code class="dcode">error</code>.

Method Route
GET /v0/avbox/play/status

Example


curl -H "Authorization: Bearer <your_api_token>" https://api-dev.headspin.io/v0/avbox/play/6c7d6c1b27a147a2af48be263ea9a517/status

Response 1: Worker in the <code class="dcode">playing</code> state


{
    "success": true,
    "finished": false,
    "hostname": "host.headspin.io",
    "device_id": "my_device",
    "media_id": "6fd55663-0aa4-416e-a752-cfab81a13701",
    "start_time": 1524884246,
    "end_time": null,
    "play": {"state": "playing"}
}

Response 2: Worker in the <code class="dcode">finished</code> stage


{
    "success": true,
    "finished": true,
    "hostname": "host.headspin.io",
    "device_id": "my_device",
    "media_id": "6fd55663-0aa4-416e-a752-cfab81a13701",
    "start_time": 1524884246,
    "end_time": 1524884557,
    "play": {"state": "finished"}
}

Wait for playback worker

When starting a playback worker, your test may need to wait for the worker to finish before proceeding. While this can be achieved by polling status, a simpler and more direct approach is to make a <code class="dcode">wait</code> request. A <code class="dcode">wait</code> request will block until the worker has run to completion and will then respond with the status. It is important to configure your client to correctly handle timeouts in the case of long-running workers.

The status of a worker will be cached once it runs to completion, but the cache will expire if the status is not accessed for 7 days. If the worker has already finished and its status is cached, the request will return immediately.

Method Route
GET /v0/avbox/play/wait

Example


curl -H "Authorization: Bearer <your_api_token>" https://api-dev.headspin.io/v0/play/6c7d6c1b27a147a2af48be263ea9a517/wait

Response


{
    "success": true,
    "finished": true,
    "hostname": "host.headspin.io",
    "device_id": "my_device",
    "media_id": "6fd55663-0aa4-416e-a752-cfab81a13701",
    "start_time": 1524884246,
    "end_time": 1524884557,
    "play": {"state": "finished"}
}

Stop playback worker

The worker can only be stopped during the <code class="dcode">playing</code> state.

Method Route
POST /v0/avbox/play/stop

Example


curl --request POST -H "Authorization: Bearer <your_api_token>" https://api-dev.headspin.io/v0/avbox/play/6c7d6c1b27a147a2af48be263ea9a517/stop

Response


{
    "success": true
}

List Workers

List playback workers.

Method Route
GET /v0/avbox/play/workers/

Example


curl -H "Authorization: Bearer <your_api_token>" https://api-dev.headspin.io/v0/avbox/play/workers/my_device@host.headspin.io

Response


{
    "success": true,
    "workers":[
        {
            "success": true,
            "finished": false,
            "hostname": "host.headspin.io",
            "device_id": "my_device",
            "media_id": "6fd55663-0aa4-416e-a752-cfab81a13701",
            "start_time": 1524884246,
            "end_time": null,
            "play": {"state": "playing"}
        }
    ]
}

Recording

This API allows audio recording from a device which is then uploaded to a storage system and made available to other users in your organization. A successful start request returns a <code class="dcode">worker_id</code> which can be used to poll for status updates or prematurely stop the worker. Once a recording is obtained its audio_id can be used with the audio API.

Start recording worker

Method Route
POST /v0/avbox/record/start

Request Body

The request body must be a JSON object with the required <code class="dcode">device_address</code>, <code class="dcode">max_duration</code> and <code class="dcode">screen</code> fields, as shown in the following example:


{
    "device_address": "my_device@host.headspin.io",
    "screen": "front",
    "max_duration": 300,
    "tag": "a helpfully descriptive tag"
}
  • device_address has the following structure: device_id@hostname.
    • device_id must be a device on the host and hostname must be in the user's pool.
    • The specified device should always be the DUT (device under test), not an A/V Box peer device such as the CD (camera device) or AD (auxiliary device). The device which is used to record the audio is determined by the screen parameter instead.
  • screen specifies which device will be used for audio recording and usually has a value of "front" or "back", depending on the A/V Box configuration.
    • It refers to the "screen" of the CD or AD which is typically set up either in front of the DUT or in the back of it.
    • As a special case, if the device_address specified is that of the AD or CD instead of the DUT, then the value "self" can be used to request to record the audio on the AD or CD.
  • max_duration is defined in seconds and must be within a valid range. The worker will stop capturing after this duration if it has not already been stopped.
  • tag is optional; it can be used as a non-unique reference to the capture audio resource.

Example


curl --request POST -H "Authorization: Bearer <your_api_token>" https://api-dev.headspin.io/v0/avbox/record/start --data '{
  "device_address": "my_device@host.headspin.io",
  "screen": "back",
  "max_duration": 300,
  "tag": "a helpfully descriptive tag"}' 

Response


{
    "success": true,
    "worker_id": "139a1bbc22304dda8cbb7c6085c43580"
}

Status of recording worker

The worker can be polled for live status updates. In general recording workers can have the following states: <code class="dcode">initializing</code>, <code class="dcode">recording</code>, <code class="dcode">uploading</code>, <code class="dcode">finished</code>, or <code class="dcode">error</code>.

Method Route
GET /v0/avbox/record/status

Example


curl -H "Authorization: Bearer <your_api_token>" https://api-dev.headspin.io/v0/avbox/record/139a1bbc22304dda8cbb7c6085c43580/status 

Response: Worker in the <code class="dcode">recording</code> state


{
    "success": true,
    "finished": false,
    "hostname": "host.headspin.io",
    "device_id": "my_device",
    "audio_id": null,
    "start_time": 1524884246,
    "max_duration": 300,
    "end_time": null,
    "record": {"state": "recording"}
}

Wait for recording worker

When starting a capture worker, your test may need to wait for the worker to finish before proceeding. While this can be achieved by polling status, a simpler and more direct approach is to make a <code class="dcode">wait</code> request. A <code class="dcode">wait</code> request will block until the worker has run to completion and will then respond with the status. It is important to configure your client to correctly handle timeouts in the case of long-running workers.

The status of a worker will be cached once it runs to completion, but the cache will expire if the status is not accessed for 7 days. If the worker has already finished and its status is cached, the request will return immediately.

Method Route
GET /v0/avbox/record/wait

Example


curl -H "Authorization: Bearer <your_api_token>" https://api-dev.headspin.io/v0/avbox/record/139a1bbc22304dda8cbb7c6085c43580/wai

Response


{
    "success": true,
    "finished": true,
    "hostname": "host.headspin.io",
    "device_id": "my_device",
    "audio_id": "db34e55a-e996-4dd5-85bf-d7682630932d",
    "start_time": 1524884246,
    "end_time": 1524884546,
    "record": {"state": "finished"}
}

Stop recording worker

The worker can only be stopped while in the <code class="dcode">recording</code> state.

Method Route
POST /v0/avbox/record/stop

Example


curl --request POST -H "Authorization: Bearer <your_api_token>" https://api-dev.headspin.io/v0/avbox/record/139a1bbc22304dda8cbb7c6085c43580/stop 

Response


{
    "success": true
}

List Workers

List recording workers.

Method Route
GET /v0/avbox/record/workers/

Example


curl -H "Authorization: Bearer <your_api_token>" https://api-dev.headspin.io/v0/avbox/record/workers/my_device@host.headspin.io

Response


{
    "success": true,
    "workers":[
        {
            "success": true,
            "finished": false,
            "hostname": "host.headspin.io",
            "device_id": "my_device",
            "audio_id": "6fd55663-0aa4-416e-a752-cfab81a13701",
            "start_time": 1524884246,
            "end_time": null,
            "record": {"state": "recording"}
        }
    ]
}

Picture

Only prepared picture files can be displayed on a device. Unlike other media files displaying a picutre is a one-time action and will not need to start a worker.

Display a picture

Method Route
POST /v0/avbox/picture

Request Body

The request body must be a JSON object with the <code class="dcode">device_address</code>, <code class="dcode">screen</code> and <code class="dcode">media_id</code> fields, as shown in the following example:

Example:


{
    "device_address": "my_device@host.headspin.io",
    "screen": "front",
    "media_id": "6fd55663-0aa4-416e-a752-cfab81a13701"
}
  • device_address has the following structure: device_id@hostname.
    • device_id must be a device on the host and hostname must be in the user's pool.
    • The specified device should always be the DUT (device under test), not the AD (auxiliary device). The device the picture will be displayed on is determined by the screen parameter instead.
  • screen specifies which device will be used to display the picture and usually has a value of "front" or "back", depending on the A/V Box configuration.
    • It refers to the AD which is typically set up either in front of the DUT or in the back of it.
    • As a special case, if the device_address specified is that of the AD instead of the DUT, then the value "self" can be used to request to display the picture on the screen of the specified AD.
  • media_id must be made available for the worker on the host with a prepare request in advance.

The same optional parameters as for playback can also be specified.

Example


curl --request POST -H "Authorization: Bearer <your_api_token>" https://api-dev.headspin.io/v0/avbox/picture --data '{"device_address": "my_device@host.headspin.io", "screen": "back", "media_id": "6fd55663-0aa4-416e-a752-cfab81a13701"}'

Response

The response will indicate whether the request was successful.


{
    "state": "finished",
    "success": true
}

Color

Sometimes it can be useful to just display a screen filled with a single color on a device.

Display a color

Method Route
POST /v0/avbox/color

Request Body

The request body must be a JSON object with the <code class="dcode">device_address</code>, <code class="dcode">screen</code> and <code class="dcode">color</code> fields, as shown in the following example:

Example:


{
    "device_address": "my_device@host.headspin.io",
    "screen": "front",
    "color": "RRGGBB"
}
  • device_address has the following structure: device_id@hostname.
    • device_id must be a device on the host and hostname must be in the user's pool.
    • The specified device should always be the DUT (device under test), not the AD (auxiliary device). The device the color will be displayed on is determined by the screen parameter instead.
  • screen specifies which device will be used to display the color and usually has a value of "front" or "back", depending on the A/V Box configuration.
    • It refers to the AD which is typically set up either in front of the DUT or in the back of it.
    • As a special case, if the device_address specified is that of the AD instead of the DUT, then the value "self" can be used to request to display the color on the screen of the specified AD.
  • color is the hexadecimal color code with two digits each for red, green and blue.

Example

Display a red screen.


curl --request POST -H "Authorization: Bearer <your_api_token>" https://api-dev.headspin.io/v0/avbox/color --data '{"device_address": "my_device@host.headspin.io", "screen": "front", "color": "ff0000"}' 

Response

The response will indicate whether the request was successful.


{
    "state": "finished",
    "success": true
}