# Introduction

TELUS International provides APIs to create labeling jobs, export annotations and manage your labeling pipelines.

The proper way to go through this reference doc, in our opinion, is to first acquaint yourself with the [terminology ](/terminology)we use. Then you can jump to the [basic operations](/basic-operations/create-a-job). \
\
After that, based on the type of project you have set up in Ground Truth Studio (GT Studio), you can refer the various examples:

* [Image Annotation](/image-annotation)
* [Image Segmentation](/image-segmentation)
* [Video Annotation](/video-annotation)
* [3D Point Cloud Annotation](https://playment.gitbook.io/api-reference/3d-point-cloud-annotation)
* [Point Cloud Segmentation](https://playment.gitbook.io/api-reference/point-cloud-segmentation)


# Terminology

| Term             | Description                                                                                                                                                                                              |
| ---------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **`Project`**    | A project is a unique labeling pipeline within which you define annotation specifications and create labeling jobs.                                                                                      |
| **`Job`**        | A job represents a unit of data to be labeled. As an example, For each image or video you want to label, you can create a separate job. An annotator can work on one job at a time.                      |
| **`Batch`**      | A batch is a collection of jobs. We recommend using batches to group datasets you use internally, or to group jobs which are part of a weekly submission.                                                |
| **`Workflow`**   | A workflow is an interactive visual representation of your labeling pipeline. When you create jobs, they move into a workflow and *flow* through the steps in the workflow till they reach the end step. |
| **`Attachment`** | An attachment is any image, PNG, PCD or JSON file associated with a job. These can be the images you want to label, or they can be the JSON file in which you fetch results.                             |


# Authentication

GT Studio uses API keys for authentication. You can create your personal API keys by navigating to the [API keys](https://jarvis.playment.io/#/settings/apiKey) page inside GT Studio settings.

<figure><img src="https://1898243238-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MAyflu2a3TSnjJox7Sw%2Fuploads%2FULUNr0g08G4uyZfEVO5h%2FAPI_key_gen.gif?alt=media&amp;token=0eefcb04-6e19-40de-a9a8-3adb573a0574" alt=""><figcaption><p>API Key generation dashboard in GT studio</p></figcaption></figure>

GT Studio expects your API key to be present in the `x-api-key` header of all API requests.


# Create a batch

Before you create jobs, you need to create a batch to put those jobs in.

A batch is a collection of jobs. We recommend using batches to group datasets you use internally, or to group jobs which are part of a weekly submission.

## A BATCH

<mark style="color:green;">`POST`</mark> `https://api.playment.io/v1/projects/:project_id/batch`

This endpoint allows you to create a batch

#### Path Parameters

| Name        | Type   | Description                                             |
| ----------- | ------ | ------------------------------------------------------- |
| project\_id | string | ID of the project in which you want to create the batch |

#### Headers

| Name      | Type   | Description                |
| --------- | ------ | -------------------------- |
| x-api-key | string | API key for authentication |

#### Request Body

| Name        | Type   | Description                                        |
| ----------- | ------ | -------------------------------------------------- |
| name        | string | Name of the batch                                  |
| description | string | Help others understand what this batch consists of |

{% tabs %}
{% tab title="200 " %}

```javascript
{
    "success": True,
    "data":{
        "batch_id": "c9970ee2-6979-46f1-95db-eee0176294a8"
    }
}
```

{% endtab %}
{% endtabs %}

The `batch_id` received in the response can be used to organize the jobs being created via the job creation API.

You can see the newly created batch inside the project in the GT Studio Jarvis dashboard.

![](https://1898243238-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MAyflu2a3TSnjJox7Sw%2F-MV-yZ8u5O2N9m3sJUSc%2F-MV007Nx5C3ahVeN6EBN%2Fimage.png?alt=media\&token=b21b4715-ac4f-4569-88c8-258b838aee77)


# Create a job

A JOB

<mark style="color:green;">`POST`</mark> `https://api.playment.io/v1/projects/:project_id/jobs`

This endpoint allows you to create a job

#### Path Parameters

| Name        | Type   | Description                                           |
| ----------- | ------ | ----------------------------------------------------- |
| project\_id | string | ID of the project in which you want to create the job |

#### Headers

| Name      | Type   | Description                |
| --------- | ------ | -------------------------- |
| x-api-key | string | API key for authentication |

#### Request Body

| Name           | Type   | Description                                                                                                                                                                                                                                                                                                            |
| -------------- | ------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| batch\_id      | string | <p>A batch is a way to organize multiple jobs under one <code>batch\_id</code>.  You can create new batches from the dashboard or by using the batch creation API.<br><br>If <code>batch\_id</code> is left empty or the key is not present, the job is created in the <code>Default batch</code> in your project.</p> |
| work\_flow\_id | string | The ID of the workflow inside which you want to create the job                                                                                                                                                                                                                                                         |
| data           | object | The `data` object contains all the information and attachments required to label a job. The `data` object is defined below                                                                                                                                                                                             |
| reference\_id  | string | Your unique identifier for the job. We suggest you use a UUID or incremental counter such that each job has a unique reference\_id                                                                                                                                                                                     |

{% tabs %}
{% tab title="200 Job successfully created" %}

```javascript
{
  "data": {
    "job_id": "3f3e8675-ca69-46d7-aa34-96f90fcbb732",
    "reference_id": "001",
    "work_flow_id": "2aae1234-acac-1234-eeff-12a22a237bbc"
  },
  "success": true
}
```

{% endtab %}

{% tab title="400 " %}

```javascript
{
    "error": {
        "code": "FS_0003",
        "message": "Invalid data passed",
        "errors": [
            {
                "validation_code": "MANDATORY_FIELD_EMPTY",
                "meta_data": {
                    "fields": [
                        "sensor_data"
                    ]
                }
            }
        ]
    },
    "success": false
}
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
After creating the job, please store the `job_id` received in the response. You'll use this `job_id` to get the annotations later.
{% endhint %}

## Body Parameters

### Project ID

After opening a project, You can find the `project_id` in the information tooltip or URL.

![](https://1898243238-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MAyflu2a3TSnjJox7Sw%2F-MSbXld2Ba66tB46Tclo%2F-MSbZdk6WTq-M6QFEwDc%2Fproject_id.png?alt=media\&token=bfdca1fe-e217-49eb-b886-575a016cb566)

### Workflow ID

![](https://1898243238-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MAyflu2a3TSnjJox7Sw%2F-MUCb_ig5QhGesg3hZJ1%2F-MUCbvB53uYhRW1hj5Ak%2F2021-02-23%2012_11_57-Projects.png?alt=media\&token=568984f6-bdb3-41e0-b1a9-20d31a9f9bd2)

### Batch ID

In the Batches section of a project, You can find the `batch_id` in the batch information tooltip.

![](https://1898243238-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MAyflu2a3TSnjJox7Sw%2F-MSbXld2Ba66tB46Tclo%2F-MSbZa7gkDjcsDdCroEY%2Fbatch_id.png?alt=media\&token=c4198687-15e5-49ce-88e7-f7d87b511c32)

### Payload

The payload data structure varies depending on the type of task

#### Image Annotation & Image Segmentation

{% code title="" %}

```javascript
{  
   "reference_id":"001",
   "data":{
     "image_url":"https://s3.aws.com/600x400/000/fff.jpg"
   },
   "work_flow_id":"2aae1234-acac-1234-eeff-12a22a237bbc"
}
```

{% endcode %}

#### Video Annotation

{% code title="" %}

```javascript
{  
   "reference_id":"001",
   "data":{
     "video_data": {
      "frames": [
        {
          "frame_id": "frame001",
          "src": "https://dummyimage.com/600x400/000/fff.jpg"
        },
        {
          "frame_id": "frame002",
          "src": "https://dummyimage.com/600x400/000/fff.jpg"
        },
        {
          "frame_id": "frame003",
          "src": "https://dummyimage.com/600x400/000/fff.jpg"
        },
        {
          "frame_id": "frame004",
          "src": "https://dummyimage.com/600x400/000/fff.jpg"
        },
        {
          "frame_id": "frame005",
          "src": "https://dummyimage.com/600x400/000/fff.jpg"
        }
      ]
    }
   },
   "work_flow_id":"2aae1234-acac-1234-eeff-12a22a237bbc"
}
```

{% endcode %}

## Attachment Access

The attachments you pass in the job creation requests ultimately need to be made available to the annotators who make the annotations in GT Studio. Depending on the type of workforce and whether you agree to give TELUS International access to your data, there are a couple of methods through which you can provide access to these attachments:

| Workforce Type                     | TELUS International can access? | Method                                                 |
| ---------------------------------- | ------------------------------- | ------------------------------------------------------ |
| Managed by TELUS International     | Yes                             | [Secure Access](/secure-attachment-access/attachments) |
| Not managed by TELUS International | Yes                             | [Secure Access](/secure-attachment-access/attachments) |
| Not managed by TELUS International | No                              | [Hybrid Cloud](/secure-attachment-access/hybrid-cloud) |

<figure><img src="https://1898243238-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MAyflu2a3TSnjJox7Sw%2Fuploads%2Fu9WeM5Sx4heI3Rn18TUG%2FDC%20App%20Explainer%20Style%20Frames.png?alt=media&amp;token=2cd00e5f-7d0f-4299-b886-e0face23c0ff" alt=""><figcaption></figcaption></figure>

## Errors

For details on possible errors, please follow this link:

{% content-ref url="/pages/-MSbaltTt1M5dhW-ykLN" %}
[Error Codes](/error-codes/error-codes)
{% endcontent-ref %}


# Get project details

## PROJECT BATCHES

<mark style="color:blue;">`GET`</mark> `https://api.playment.io/v1/projects/:project_id/details`

Get list of batches in a project

#### Path Parameters

| Name        | Type   | Description                                         |
| ----------- | ------ | --------------------------------------------------- |
| project\_id | string | ID of the project for which you want to get batches |

#### Headers

| Name      | Type   | Description                |
| --------- | ------ | -------------------------- |
| x-api-key | string | API key for authentication |

{% tabs %}
{% tab title="200 " %}

```javascript
{
    "data": {
        "name": "Project XYZ",
        "base": "IMAGE",
        "batches": [
            {
                "id": "27f8303e-69fd-4b54-a4e9-63456571e195",
                "name": "Batch 1",
                "description": "These are the jobs created on 23rd August",
                "is_default": false,
                "total_jobs": 1427,
                "completed_jobs": 1427,
                "total_frames": 1427,
                "completed_frames": 1427,
                "annotations": 9392,
                "created_at": "2019-08-23T17:55:13.203229+05:30",
                "status": "Complete"
            },
            {
                "id": "10cab3e9-3f26-4c8b-83ac-3c138685120b",
                "name": "b2",
                "description": "",
                "is_default": false,
                "total_jobs": 4996,
                "completed_jobs": 4996,
                "total_frames": 4996,
                "completed_frames": 4996,
                "annotations": 12121,
                "created_at": "2019-12-06T15:42:36.23401+05:30",
                "status": "Complete"
            }            
        ]
    },
    "success": true
}
```

{% endtab %}
{% endtabs %}

You can iterate over the list of batches received in the response to call the [Get batch jobs API](/basic-operations/get-batch-jobs), which will give you a list of all the jobs in a batch. You can then iterate over this list and call the [Get job result API](/basic-operations/get-job-results) to get the annotation results for each job.&#x20;


# Get batch jobs

## BATCH JOBS

<mark style="color:blue;">`GET`</mark> `https://api.playment.io/v1/projects/:project_id/batch/:batch_id?page_token=:next_page_token`

Get a list of all jobs in a batch.\
The number of jobs in a batch is usually huge, so this API has pagination

#### Path Parameters

| Name              | Type   | Description                                                                                                                                                                               |
| ----------------- | ------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| next\_page\_token | string | You can leave this parameter blank for the first page. In the response of the first page, you'll get a token against the `data.next_page_token` key. Use this token to get the next page. |
| batch\_id         | string | ID of the batch for which you want to fetch a list of jobs                                                                                                                                |
| project\_id       | string | ID of the project which has this batch                                                                                                                                                    |

#### Headers

| Name      | Type   | Description                |
| --------- | ------ | -------------------------- |
| x-api-key | string | API key for authentication |

{% tabs %}
{% tab title="200 " %}

```javascript
{
    "data": {
        "id": "",
        "project_id": "",
        "name": "Batch 1",
        "jobs": [
            {
                "id": "fde5ert6-eb32-481a-807a-03a0428ca836",
                "reference_id": "001",
                "status": "completed",
                "frames": 1,
                "annotations": 1
            },
            {
                "id": "fdda8970-dr3d-4978-9ce3-e80654d8078c",
                "reference_id": "002",
                "status": "completed",
                "frames": 1,
                "annotations": 1
            }
        ],
        "next_page_token": "1575822103313046000"
    },
    "success": true
}
```

{% endtab %}
{% endtabs %}

You can iterate over the list of jobs received in the response and call the [Get job result API](/basic-operations/get-job-results) to get the annotation results for each job.&#x20;


# Get job result

## JOB RESULT

<mark style="color:blue;">`GET`</mark> `https://api.playment.io/v1/projects/:project_id/jobs/:job_id`

This endpoint allows you to get the annotations created on a job.

#### Path Parameters

| Name        | Type   | Description                                                                              |
| ----------- | ------ | ---------------------------------------------------------------------------------------- |
| job\_id     | string | ID of the job. You would have received this ID in the response when you created the job. |
| project\_id | string | ID of the project where the job was created                                              |

#### Headers

| Name      | Type   | Description                |
| --------- | ------ | -------------------------- |
| x-api-key | string | API key for authentication |

{% tabs %}
{% tab title="200 Job results successfully retrieved." %}

```javascript
{
    "data": {
        "project_id": "905ea3ee-6f62-4bb7-8c31-471e486d9202",
        "reference_id": "001",
        "job_id": "3f3e8675-ca69-46d7-aa34-96f90fcbb732",
        "batch_id": "468b6ae3-e98d-4d08-9427-b6e7a016054c",
        "status": "completed",
        "work_flow_id": "51bb440c-f0ed-4286-8984-ea399cbc1f9w",
        "priority_weight": 5,
        "tag": "2aae1234-acac-1234-eeff-12a22a237bbc", //tag is the workflow_id for the job  
        "result": "https://playment-data-uploads.s3.ap-south-1.amazonaws.com/sample-result.json"
    },
    "success": true
}
```

{% endtab %}
{% endtabs %}

## ATTACHMENT

<mark style="color:blue;">`GET`</mark> `https://api.playment.io/v1/attachments?url=:result_url`

The *result\_url* (`data.result`) returned by the GET Job result API is a private URL (Well, it's public till 15th July 2021, after which we'll enforce it to be private). You need to use this Attachment access API to securely fetch the results. Please refer to the Attachment Access API document for more detail.&#x20;

#### Path Parameters

| Name        | Type   | Description                                   |
| ----------- | ------ | --------------------------------------------- |
| result\_url | string | Result URL returned by the GET job result API |

#### Headers

| Name      | Type   | Description                |
| --------- | ------ | -------------------------- |
| x-api-key | string | API key for authentication |

{% tabs %}
{% tab title="200 " %}

```
The API will redirect to a signed URL of the attachment
```

{% endtab %}
{% endtabs %}

#### Reference python script to get the job result of a batch

```python
import requests
import json
import os
import urllib.request
x_api_key = ""
project_id = ""
batch_id = ""

def get_batch_job(project_id, batch_id, x_api_key,next_page_token):
    base_url = "https://api.playment.io/v1/projects/{}/batch/{}?page_token={}".format(
        project_id, batch_id, next_page_token
    )
    headers = {"x-api-key": x_api_key}
    response = requests.get(base_url, headers=headers)
    # print(response.json())
    if response.status_code >= 500:
        raise Exception(response.text)
    if 400 <= response.status_code < 500:
        raise Exception(response.text)
    return response.json()

def get_job_result(project_id,job_id, x_api_key):
    base_url = "https://api.playment.io/v1/projects/{}/jobs/{}".format(project_id,job_id)
    headers = {"x-api-key": x_api_key}
    response = requests.get(base_url, headers=headers)
    # print(response.json())
    if response.status_code >= 500:
        raise Exception(response.text)
    if 400 <= response.status_code < 500:
        raise Exception(response.text)
    return response.json()

def get_attachment(result_url, x_api_key):
    base_url = "https://api.playment.io/v1/attachments?url={}".format(result_url)
    headers = {"x-api-key": x_api_key}
    response = requests.get(base_url, headers=headers)
    # print(response.json())
    if response.status_code >= 500:
        raise Exception(response.text)
    if 400 <= response.status_code < 500:
        raise Exception(response.text)
    return response.json()

if __name__ == "__main__":
    batch_res = get_batch_job(project_id, batch_id, x_api_key,'')
    jobs = batch_res['data']['jobs']

    while 'next_page_token' in batch_res['data'].keys():
        next_page_token = batch_res['data']['next_page_token']
        batch_res = get_batch_job(project_id, batch_id, x_api_key,next_page_token)
        jobs = jobs + batch_res['data']['jobs']


    # Set the desired folder struture/name here
    folder_name = batch_id

    for job in jobs:
        job_res = get_job_result(project_id,job['id'],x_api_key)
        job_annotation_result = get_attachment(job_res['data']['result'],x_api_key)

        # Set the filename here
        file_name = job['id'] + '.json'
        with open(os.path.join(folder_name, file_name),'w') as outfile:
            json.dump(job_annotation_result, outfile)
        print(job['id'])
```


# Image Annotation

Here's a short example to understand how to create an image annotation job and export the results once the job has been labeled.

A new job needs to be created for each image you want to label.

{% content-ref url="/pages/-MSbEPdD\_3aRhZajyLdr" %}
[Create a job](/image-annotation/create-a-job)
{% endcontent-ref %}


# Create a job

## A JOB

<mark style="color:green;">`POST`</mark> `https://api.playment.io/v1/projects/:project_id/jobs`

This endpoint allows you to create a job

#### Path Parameters

| Name        | Type   | Description                                           |
| ----------- | ------ | ----------------------------------------------------- |
| project\_id | string | ID of the project in which you want to create the job |

#### Headers

| Name      | Type   | Description                |
| --------- | ------ | -------------------------- |
| x-api-key | string | API key for authentication |

#### Request Body

| Name           | Type   | Description                                                                                                                                                                                                                                                                                                            |
| -------------- | ------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| batch\_id      | string | <p>A batch is a way to organize multiple jobs under one <code>batch\_id</code>.  You can create new batches from the dashboard or by using the batch creation API.<br><br>If <code>batch\_id</code> is left empty or the key is not present, the job is created in the <code>Default batch</code> in your project.</p> |
| work\_flow\_id | string | The ID of the workflow inside which you want to create the job                                                                                                                                                                                                                                                         |
| data           | object | The `data` object contains all the information and attachments required to label a job. The `data` object is defined below                                                                                                                                                                                             |
| reference\_id  | string | The unique identifier of the job                                                                                                                                                                                                                                                                                       |

{% tabs %}
{% tab title="200 " %}

```javascript
{
  "data": {
    "job_id": "3f3e8675-ca69-46d7-aa34-96f90fcbb732",
    "reference_id": "001",
    "work_flow_id": "2aae1234-acac-1234-eeff-12a22a237bbc"
  },
  "success": true
}
```

{% endtab %}
{% endtabs %}

## Payload

```javascript
{
  "reference_id": "001",
  "data": {
    "image_url": "https://s3.aws.com/600x400/000/fff.jpg&text=Dummy+Image+1",
    "reference_data": {
      "vector": {
        "images": [
          {
            "image_url": "https://s3.aws.com/600x400/000/fff.jpg&text=Dummy+Image+1",
            "label": "camera 1"
          },
          {
            "image_url": "https://s3.aws.com/600x400/000/fff.jpg&text=Dummy+Image+1",
            "label": "camera 2"
          }
        ]
      }
    }
  },
  "work_flow_id": "2aae1234-acac-1234-eeff-12a22a237bbc"
}
```

## Payload Definition

| Key                   | Type     | Description                                                                                                                                                                                                                                                                                                                                                                                                                            |
| --------------------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `data.reference_data` | `Object` | <p>The <code>reference\_data</code> object contains an additional list of images that can be used as a reference while annotating the primary image.<br>This is an <code>optional</code> key based on your requirement.<br><code>data.reference\_data.vector.images</code> is an array of reference images where each object has 2 keys :<br><code>image\_url</code> - URL of the image.<br><code>label</code>- Name of the image.</p> |
| `data.image_url`      | `string` | URL of the image.                                                                                                                                                                                                                                                                                                                                                                                                                      |

## Code Example

{% tabs %}
{% tab title="Python" %}

```python
import requests
import json

"""
Details for creating JOBS,
project_id  ->> ID of project in which the job will be created
x_api_key   ->> API key for authentication 
workflow_id ->> The workflow in which the job will be created
batch_id    ->> The batch in which job will be created
"""

# Additional helper function to create a batch
def create_batch(BATCH_NAME):
    base_url = f"https://api.playment.io/v1/projects/{PROJECT_ID}/batch"
    DATA = {"name":BATCH_NAME}
    response = requests.post(base_url, headers={'x-api-key': CLIENT_KEY}, json=DATA)
    response_data = response.json()
    if response.status_code >= 500:
        raise Exception(f"Something went wrong at Playment's end {response.status_code}")
    if 400 <= response.status_code < 500:
        raise Exception(f"{response_data['error']['message']} {response.status_code}")
    print(response_data)
    return response_data
    
#method that can be used to call the job creation api
def create_job(project_id, data, x_api_key):
    base_url = "https://api.playment.io/v1/projects/{}/jobs".format(project_id)
    headers = {'x-api-key': x_api_key}
    response = requests.post(base_url, headers=headers, json=data)
    
    print(response.json())
    if response.status_code >= 500:
        raise Exception(response.text)
    if 400 <= response.status_code < 500:
        raise Exception(response.text)
    return response.json()

if __name__ == "__main__":
    #list of frames in a single job
    image_url = "https://example.com/image_url_1"
    ref_image_url1 = "https://example.com/ref_image_url_1"
    ref_image_url2 = "https://example.com/ref_image_url_2"
    
    #reference_id should be unique for each job
    reference_id= "job1"

    project_id = ''
    x_api_key = ''
    workflow_id = ''
    batch_id = ''
    
    
    job_data = {
        'reference_id':reference_id,
        'work_flow_id':workflow_id,
        'data':{
            'image_url':image_url,
            'reference_data': {
                  'vector': {
                    'images': [
                      {
                        'image_url': ref_image_url1,
                        'label': 'camera 1'
                      },
                      {
                        'image_url': ref_image_url2,
                        'label': 'camera 2'
                      }
                    ]
                  }
                }
            },
        'batch_id': batch_id
    }
    
    response = create_job(project_id=project_id, data=job_data, x_api_key= x_api_key)
    print(response)
    
```

{% endtab %}
{% endtabs %}

## Creating jobs with pre-labeled data

If you have data which has been labeled previously by an ML model or by human labelers, you can create jobs with such labels already created. To do this, you need to send the annotation data in the `data.maker_response` key in the payload. The annotation data needs to be in our annotation format.

Here's an example

```javascript
{  
   "reference_id":"001",
   "data":{
     "image_url":"https://s3.aws.com/600x400/000/fff.jpg&text=Dummy+Image+1",
     "maker_response" : {
        "rectangles": {
           "data": []
        },
        "polygons": {
           "data": []
        },
        "lines": {
           "data": []
        },
        "cuboids": {
           "data": []
        },
        "landmarks": {
           "data": []
        }
    }
   },
   "work_flow_id":"2aae1234-acac-1234-eeff-12a22a237bbc"
}
```

Each object in the `data.maker_response.rectangles.data` list will be an annotation object of the respective annotation type. For example:

{% tabs %}
{% tab title="Rectangle" %}

```javascript
{
  "_id": "0e6d895e-2484-439a-b62b-d8a0afb3d190",
  "label": "Cat".
  "attributes": {
    "pose": {
      "value": "standing"
    },
    "breed": {
      "value": "Persian"
    }
  },
  "coordinates": [
    {"x": 0.00398, "y": 0.00558},
    {"x": 0.05404, "y": 0.00558},
    {"x": 0.05404, "y": 0.09096},
    {"x": 0.00398, "y": 0.09096}
  ]
}
```

{% endtab %}

{% tab title="Polygons" %}

```javascript
{
  "_id": "8f8897ad-e07b-4e55-9dbe-61f6b9df85c5",
  "label": "face_mask",
  "attributes": {
    "covers_nose": {
      "value": "Yes"
    },
  }
  "points": {
    "p1": {"x": 0.286774, "y": 0.892502},
    "p2": {"x": 0.385849, "y": 0.576888},
    "p3": {"x": 0.426721, "y": 0.469081},
    "p4": {"x": 0.288623, "y": 0.253878},
    "p5": {"x": 0.148623, "y": 0.353878}
  },
  "edges": {
    "e1": ["p1", "p2"],
    "e2": ["p2", "p3"],
    "e3": ["p3", "p4"],
    "e4": ["p4", "p4"],
    "e5": ["p5", "p1"]
  }
}
```

{% endtab %}

{% tab title="Lines" %}

```javascript
{
  "_id": "8f8897ad-e07b-4e55-9dbe-61f6b9df85c5",
  "label": "lane_divider",
  "attributes": {
    "raised": {
      "value": "Yes"
    },
  }
  "points": {
    "p1": {"x": 0.286774, "y": 0.892502},
    "p2": {"x": 0.285849, "y": 0.876888},
    "p3": {"x": 0.286774, "y": 0.869081},
    "p4": {"x": 0.288623, "y": 0.853878}
  }
}
```

{% endtab %}

{% tab title="Cuboids" %}

```javascript
{
  "_id": "8f8897ad-e07b-4e55-9dbe-61f6b9df85c5",
  "label": "Car",
  "attributes" : {
    "faces_visible": {
      "value": ["right","back"]
    }
  },
  "points": {
    "p1": {"x": 0.17,"y": 0.58},
    "p2": {"x": 0.26,"y": 0.58},
    "p3": {"x": 0.26,"y": 0.49},
    "p4": {"x": 0.17,"y": 0.49},
    "p5": {"x": 0.24,"y": 0.51},
    "p6": {"x": 0.35,"y": 0.52},
    "p7": {"x": 0.35,"y": 0.36},
    "p8": {"x": 0.25,"y": 0.37}
  },
  "front": {
    "coordinates": ["p1","p2","p3","p4"]
  },
  "side": {
    "coordinates": ["p2","p3","p5","p6"]
  },
  "back": {
    "coordinates": ["p7","p8","p5","p6"]
  }
}
```

{% endtab %}

{% tab title="Landmarks" %}

```javascript
{
  "_id": "e7e3353f-2ffe-432a-a14f-9cb9a6f4b735",
  "label": "nose",
  "attributes": {
    "visible": {
      "value": "Partially"
    },
  }
  "points": {
    "p1": { "x": 0.17, "y": 0.58, "label": 1 },
    "p2": { "x": 0.26, "y": 0.63, "label": 2 },
    "p3": { "x": 0.27, "y": 0.63, "label": 3 },
    "p4": { "x": 0.29, "y": 0.59, "label": 4 },
    "p5": { "x": 0.25, "y": 0.46, "label": 5 },
    "p6": { "x": 0.22, "y": 0.42, "label": 6 }
  }
}
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
In our annotation output, the **x and y coordinates are normalised** to ensure consistency across different image sizes. Normalisation is crucial for accurately representing object positions relative to the image dimensions.

**X and Y Coordinates:**

* **X Coordinate:**
  * Normalised x coordinates ($$Xnorm​$$) are calculated using the formula: \
    $$Xnorm = Xraw / Image Width$$
  * The result ranges from 0.0 to 1.0, where 0.0(Origin) corresponds to the leftmost edge of the image, and 1.0 corresponds to the rightmost edge.
* **Y Coordinate:**
  * Normalised y coordinates ($$Ynorm​$$) are calculated using the formula: \
    $$Ynorm = Yraw / Image Height$$
  * The result ranges from 0.0 to 1.0, where 0.0(Origin) corresponds to the topmost edge of the image, and 1.0 corresponds to the bottommost edge.
    {% endhint %}


# Get job results

## JOB RESULT

<mark style="color:blue;">`GET`</mark> `https://api.playment.io/v1/projects/:project_id/jobs/:job_id`

This endpoint allows you to get the annotations created on a job.

#### Path Parameters

| Name        | Type   | Description                                                                              |
| ----------- | ------ | ---------------------------------------------------------------------------------------- |
| job\_id     | string | ID of the job. You would have received this ID in the response when you created the job. |
| project\_id | string | ID of the project where the job was created                                              |

#### Headers

| Name      | Type   | Description                |
| --------- | ------ | -------------------------- |
| x-api-key | string | API key for authentication |

{% tabs %}
{% tab title="200 Job results successfully retrieved." %}

```javascript
{
    "data": {
        "project_id": "905ea3ee-6f62-4bb7-8c31-471e486d9202",
        "reference_id": "001",
        "job_id": "3f3e8675-ca69-46d7-aa34-96f90fcbb732",
        "batch_id": "468b6ae3-e98d-4d08-9427-b6e7a016054c",
        "status": "completed",
        "work_flow_id": "51bb440c-f0ed-4286-8984-ea399cbc1f9w",
        "priority_weight": 5,
        "tag": "2aae1234-acac-1234-eeff-12a22a237bbc", //tag is the workflow_id for the job  
        "result": "https://playment-data-uploads.s3.ap-south-1.amazonaws.com/sample-result.json"
    },
    "success": true
}
```

{% endtab %}
{% endtabs %}

## ATTACHMENT

<mark style="color:blue;">`GET`</mark> `https://api.playment.io/v1/attachments?url=:result_url`

The *result\_url* (`data.result`) returned by the GET Job result API is a private URL (Well, it's public till 15th July 2021, after which we'll enforce it to be private). You need to use this Attachment access API to securely fetch the results. Please refer to the Attachment Access API document for more detail.

#### Path Parameters

| Name        | Type   | Description                                   |
| ----------- | ------ | --------------------------------------------- |
| result\_url | string | Result URL returned by the GET job result API |

#### Headers

| Name      | Type   | Description                |
| --------- | ------ | -------------------------- |
| x-api-key | string | API key for authentication |

{% tabs %}
{% tab title="200 " %}

```
The API will redirect to a signed URL of the attachment
```

{% endtab %}
{% endtabs %}

## Result Object

```javascript
{
  "data": {
    "annotations": {
      "rectangles": [],
      "polygons": [],
      "lines": [],
      "cuboids": [],
      "landmarks": []
    },
    "image_url":"https://s3.aws.com/600x400/000/fff.jpg&text=Dummy+Image+1"
  }
}
```

The rectangles list contains objects, where each object is an annotation. You can check the data structures for various annotation types below:&#x20;

{% tabs %}
{% tab title="Rectangles" %}
![](https://1898243238-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MAyflu2a3TSnjJox7Sw%2F-MUCk3YWHepmJxcKntuA%2F-MUCkM9VbOuE7q8UxMWD%2Fbb.svg?alt=media\&token=6a8ce4a5-b35e-4935-a179-467cb7981cbb)

```javascript
"rectangles": [
  {
    "_id": "0e6d895e-2484-439a-b62b-d8a0afb3d190",
    "label": "Chair".
    "attributes": {
      "Truncation": {
        "value": "0% Truncated"
      },
      "Occlusion": {
        "value": "0% Occluded"
      }
    }
    "coordinates": [
      {"x": 0.00398, "y": 0.00558},
      {"x": 0.05404, "y": 0.00558},
      {"x": 0.05404, "y": 0.09096},
      {"x": 0.00398, "y": 0.09096}
    ]
  }
]
```

{% endtab %}

{% tab title="Polygons" %}
![](https://1898243238-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MAyflu2a3TSnjJox7Sw%2F-MUCk3YWHepmJxcKntuA%2F-MUCkaYRlEosNpzOW_v4%2Fpolygon.svg?alt=media\&token=7735d675-f8c5-488a-a040-430736b1ff9c)

```javascript
"polygons": [
  {
    "_id": "8f8897ad-e07b-4e55-9dbe-61f6b9df85c5",
    "label": "Pedestrian Crossing",
    "attributes": {
      "Type": {
        "value": "Dashed"
      },
      "Occlusion": {
        "value": "0% - 25% Occluded"
      },
      "Truncation": {
        "value": "0% Truncated"
      }
    }
    "points": {
      "p1": {"x": 0.286774, "y": 0.892502},
      "p2": {"x": 0.385849, "y": 0.576888},
      "p3": {"x": 0.426721, "y": 0.469081},
      "p4": {"x": 0.288623, "y": 0.253878},
      "p5": {"x": 0.148623, "y": 0.353878}
    },
    "edges": {
      "e1": ["p1", "p2"],
      "e2": ["p2", "p3"],
      "e3": ["p3", "p4"],
      "e4": ["p4", "p4"],
      "e5": ["p5", "p1"]
    }
  }
]
```

{% endtab %}

{% tab title="Lines" %}
![](https://1898243238-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MAyflu2a3TSnjJox7Sw%2F-MUCk3YWHepmJxcKntuA%2F-MUCkrkajq97qmWCuX4p%2Fline.svg?alt=media\&token=a7f0d7ee-f41e-4b5b-96ea-43e8e4d9f046)

```javascript
"lines": [
  {
    "_id": "8f8897ad-e07b-4e55-9dbe-61f6b9df85c5",
    "label": "Single SOlid Line",
    "attributes": {
      "Color": {
        "value": "Yellow"
      },
    }
    "points": {
      "p1": {"x": 0.286774, "y": 0.892502},
      "p2": {"x": 0.285849, "y": 0.876888},
      "p3": {"x": 0.286774, "y": 0.869081},
      "p4": {"x": 0.288623, "y": 0.853878}
    }
  }
]
```

{% endtab %}

{% tab title="Cuboids" %}
![](https://1898243238-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MAyflu2a3TSnjJox7Sw%2F-MUCk3YWHepmJxcKntuA%2F-MUCl06acI_VsbDOlEgi%2Fcuboid.svg?alt=media\&token=4c5276bf-40fe-4025-bd61-6e9fc30a82b7)

```javascript
"cuboids": [
  {
    "_id": "8f8897ad-e07b-4e55-9dbe-61f6b9df85c5",
    "label": "Car",
    "attributes" : {
      "faces_visible": {
        "value": ["right","back"]
      },
      "Type": {
        "value": "Sedan"
      }
    },
    "points": {
      "p1": {"x": 0.17,"y": 0.58},
      "p2": {"x": 0.26,"y": 0.58},
      "p3": {"x": 0.26,"y": 0.49},
      "p4": {"x": 0.17,"y": 0.49},
      "p5": {"x": 0.24,"y": 0.51},
      "p6": {"x": 0.35,"y": 0.52},
      "p7": {"x": 0.35,"y": 0.36},
      "p8": {"x": 0.25,"y": 0.37}
    },
    "front": {
      "coordinates": ["p1","p2","p3","p4"]
    },
    "side": {
      "coordinates": ["p2","p3","p5","p6"]
    },
    "back": {
      "coordinates": ["p7","p8","p5","p6"]
    }
  }
]
```

{% endtab %}

{% tab title="Landmarks" %}
![](https://1898243238-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MAyflu2a3TSnjJox7Sw%2F-MUCk3YWHepmJxcKntuA%2F-MUClBd_ttH_TwfFu2pl%2Flandmark.svg?alt=media\&token=b37cd1cf-11d1-4b0f-848c-0a4163553cbf)

```javascript
"landmarks": [
  {
    "_id": "e7e3353f-2ffe-432a-a14f-9cb9a6f4b735",
    "label": "Eye",
    "attributes": {
      "Type": {
        "value": "Open"
      },
    }
    "points": {
      "p1": { "x": 0.17, "y": 0.58, "label": 1 },
      "p2": { "x": 0.26, "y": 0.63, "label": 2 },
      "p3": { "x": 0.27, "y": 0.63, "label": 3 },
      "p4": { "x": 0.29, "y": 0.59, "label": 4 },
      "p5": { "x": 0.25, "y": 0.46, "label": 5 },
      "p6": { "x": 0.22, "y": 0.42, "label": 6 }
    }
  }
]
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
In our annotation output, the **x and y coordinates are normalised** to ensure consistency across different image sizes. Normalisation is crucial for accurately representing object positions relative to the image dimensions.

**X and Y Coordinates:**

* **X Coordinate:**
  * Normalised x coordinates ($$Xnorm​$$) are calculated using the formula: \
    $$Xnorm = Xraw / Image Width$$
  * The result ranges from 0.0 to 1.0, where 0.0(Origin) corresponds to the leftmost edge of the image, and 1.0 corresponds to the rightmost edge.
* **Y Coordinate:**
  * Normalised y coordinates ($$Ynorm​$$) are calculated using the formula: \
    $$Ynorm = Yraw / Image Height$$
  * The result ranges from 0.0 to 1.0, where 0.0(Origin) corresponds to the topmost edge of the image, and 1.0 corresponds to the bottommost edge.
    {% endhint %}


# Image Segmentation

Here's a short example to understand how to create an image segmentation job and export the results once the job has been labeled.

A new job needs to be created for each image you want to label.

{% content-ref url="/pages/-MSbKfDAr-9KSH2ybMSH" %}
[Create a job](/image-segmentation/create-a-job)
{% endcontent-ref %}


# Create a job

## A JOB

<mark style="color:green;">`POST`</mark> `https://api.playment.io/v1/projects/:project_id/jobs`

This endpoint allows you to create a job

#### Path Parameters

| Name        | Type   | Description                                           |
| ----------- | ------ | ----------------------------------------------------- |
| project\_id | string | ID of the project in which you want to create the job |

#### Headers

| Name      | Type   | Description                |
| --------- | ------ | -------------------------- |
| x-api-key | string | API key for authentication |

#### Request Body

| Name           | Type   | Description                                                                                                                                                                                                                                                                                                            |
| -------------- | ------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| batch\_id      | string | <p>A batch is a way to organise multiple jobs under one <code>batch\_id</code>.  You can create new batches from the dashboard or by using the batch creation API.<br><br>If <code>batch\_id</code> is left empty or the key is not present, the job is created in the <code>Default batch</code> in your project.</p> |
| work\_flow\_id | string | The ID of the workflow inside which you want to create the job                                                                                                                                                                                                                                                         |
| data           | object | The `data` object contains all the information and attachments required to label a job. The `data` object is defined below                                                                                                                                                                                             |
| reference\_id  | string | The unique identifier of the job                                                                                                                                                                                                                                                                                       |

{% tabs %}
{% tab title="200 " %}

```
{
  "data": {
    "job_id": "3f3e8675-ca69-46d7-aa34-96f90fcbb732",
    "reference_id": "001",
    "work_flow_id": "2aae1234-acac-1234-eeff-12a22a237bbc"
  },
  "success": true
}
```

{% endtab %}
{% endtabs %}

## Payload

```javascript
{
  "reference_id": "001",
  "data": {
    "image_url": "https://s3.aws.com/600x400/000/fff.jpg&text=Dummy+Image+1",
    "reference_data": {
      "raster": {
        "images": [
          {
            "image_url": "https://s3.aws.com/600x400/000/fff.jpg&text=Dummy+Image+1",
            "label": "camera 1"
          },
          {
            "image_url": "https://s3.aws.com/600x400/000/fff.jpg&text=Dummy+Image+1",
            "label": "camera 2"
          }
        ]
      }
    }
  },
  "work_flow_id": "2aae1234-acac-1234-eeff-12a22a237bbc"
}
```

## Payload Definition

| Key                   | Type     | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| --------------------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `data.reference_data` | `Object` | <p>The <code>reference\_data</code> object contains an additional list of images that can be used as a reference while annotating the primary image.</p><p>This is an <code>optional</code> key based on your requirement. </p><p></p><p><code>data.reference\_data.raster.images</code> is an array of reference images where each object has 2 keys :</p><p><code>image\_url</code> - URL of the image</p><p><code>label</code>- Name of the image. </p> |
| `data.image_url`      | `string` | URL of the image.                                                                                                                                                                                                                                                                                                                                                                                                                                          |

## Code Example

{% tabs %}
{% tab title="Python" %}

```python
import requests
import json

"""
Details for creating JOBS,
project_id  ->> ID of project in which the job will be created
x_api_key   ->> API key for authentication 
workflow_id ->> The workflow in which the job will be created
batch_id    ->> The batch in which job will be created
"""

# Additional helper function to create a batch
def create_batch(BATCH_NAME):
    base_url = f"https://api.playment.io/v1/projects/{PROJECT_ID}/batch"
    DATA = {"name":BATCH_NAME}
    response = requests.post(base_url, headers={'x-api-key': CLIENT_KEY}, json=DATA)
    response_data = response.json()
    if response.status_code >= 500:
        raise Exception(f"Something went wrong at Playment's end {response.status_code}")
    if 400 <= response.status_code < 500:
        raise Exception(f"{response_data['error']['message']} {response.status_code}")
    print(response_data)
    return response_data
    
#method that can be used to call the job creation api
def create_job(project_id, data, x_api_key):
    base_url = "https://api.playment.io/v1/projects/{}/jobs".format(project_id)
    headers = {'x-api-key': x_api_key}
    response = requests.post(base_url, headers=headers, json=data)
    
    print(response.json())
    if response.status_code >= 500:
        raise Exception(response.text)
    if 400 <= response.status_code < 500:
        raise Exception(response.text)
    return response.json()

if __name__ == "__main__":
    #list of frames in a single job
    image_url = "https://example.com/image_url_1"
    ref_image_url1 = "https://example.com/ref_image_url_1"
    ref_image_url2 = "https://example.com/ref_image_url_2"
    
    #reference_id should be unique for each job
    reference_id= "job1"

    project_id = ''
    x_api_key = ''
    workflow_id = ''
    batch_id = ''
    
    
    job_data = {
        'reference_id':reference_id,
        'work_flow_id':workflow_id,
        'data':{
            'image_url':image_url,
            'reference_data': {
                  'raster': {
                    'images': [
                      {
                        'image_url': ref_image_url1,
                        'label': 'camera 1'
                      },
                      {
                        'image_url': ref_image_url2,
                        'label': 'camera 2'
                      }
                    ]
                  }
                }
            },
        'batch_id': batch_id
    }
    
    response = create_job(project_id=project_id, data=job_data, x_api_key= x_api_key)
    print(response)
    
```

{% endtab %}
{% endtabs %}

## Creating jobs with pre-labeled data

If you have data which has been labeled previously by an ML model or by human labelers, you can create jobs with such labels already created. To do this, you need to send the annotation data in the `data.maker_response` key in the payload. The annotation data needs to be in our annotation format.

Here's an example:

```javascript
{  
   "reference_id":"001",
   "data":{
     "image_url":"https://s3.aws.com/600x400/000/fff.jpg&text=Dummy+Image+1",
     "maker_response" : {
        "raster": {
           "data": {
              "legend": {
                "#fdffd34": "Person 1",
                "#f23334": "Car 1",
                "#fd2d34": "Sky" 
              },
              "url": "https://example.s3.ap-south-1.amazonaws.com/mask001.png"
           }
        }
      }
   },
   "work_flow_id":"2aae1234-acac-1234-eeff-12a22a237bbc"
}
```

The object at the end of`data.maker_response.raster.data.url` should be a PNG file with four 8-bit channels. The first 3 channels are R, G & B respectively. The hex code for these RGB values for any pixel should map to a class or instance based on the`legend` object. Un-labeled pixels should have each channel as 0.


# Get job results

## JOB RESULT

<mark style="color:blue;">`GET`</mark> `https://api.playment.io/v1/projects/:project_id/jobs/:job_id`

This endpoint allows you to get the annotations created on a job.

#### Path Parameters

| Name        | Type   | Description                                                                              |
| ----------- | ------ | ---------------------------------------------------------------------------------------- |
| job\_id     | string | ID of the job. You would have received this ID in the response when you created the job. |
| project\_id | string | ID of the project where the job was created                                              |

#### Headers

| Name      | Type   | Description                |
| --------- | ------ | -------------------------- |
| x-api-key | string | API key for authentication |

{% tabs %}
{% tab title="200 Job results successfully retrieved." %}

```javascript
{
    "data": {
        "project_id": "905ea3ee-6f62-4bb7-8c31-471e486d9202",
        "reference_id": "001",
        "job_id": "3f3e8675-ca69-46d7-aa34-96f90fcbb732",
        "batch_id": "468b6ae3-e98d-4d08-9427-b6e7a016054c",
        "status": "completed",
        "work_flow_id": "51bb440c-f0ed-4286-8984-ea399cbc1f9w",
        "priority_weight": 5,
        "tag": "2aae1234-acac-1234-eeff-12a22a237bbc",//tag is the workflow_id for the job  
        "result": "https://playment-data-uploads.s3.ap-south-1.amazonaws.com/sample-result.json"
    },
    "success": true
}
```

{% endtab %}
{% endtabs %}

## ATTACHMENT

<mark style="color:blue;">`GET`</mark> `https://api.playment.io/v1/attachments?url=:result_url`

The *result\_url* (`data.result`) returned by the GET Job result API is a private URL (Well, it's public till 15th July 2021, after which we'll enforce it to be private). You need to use this Attachment access API to securely fetch the results. Please refer to the Attachment Access API document for more detail.

#### Path Parameters

| Name        | Type   | Description                                   |
| ----------- | ------ | --------------------------------------------- |
| result\_url | string | Result URL returned by the GET job result API |

#### Headers

| Name      | Type   | Description                |
| --------- | ------ | -------------------------- |
| x-api-key | string | API key for authentication |

{% tabs %}
{% tab title="200 " %}

```
The API will redirect to a signed URL of the attachment
```

{% endtab %}
{% endtabs %}

## Result Object

{% tabs %}
{% tab title="Simple Segmentation" %}

```javascript
{
  "legend": {
    "#fdffd34": "Car",
    "#f23334": "Sky",
    "#fd2d34": "Tree" 
  },
  "url": "https://playment-data-uploads.s3.ap-south-1.amazonaws.com/clients/e81bddc9-e39c-4a7f-bef4-caee6f757009/projects/6f5ed111-1a46-4e06-8d72-c0dec50ac0b7/batch_export_result/0f0abfb5-4c5f-4838-a89e-92d5234b0b09/576d8391-0ce5-4cd4-969a-f3806e1cf2f4/source.png"
}
```

{% endtab %}

{% tab title="Instance Aware Segmentation" %}

```javascript
{
  "legend": {
    "#00c537": "car # 1",
    "#01d9fc": "pedestrian # 1",
    "#fac1c2": "pedestrian # 2",
    "#fb0379": "pedestrian # 3",
    "#fcbe92": "car # 2",
    "#fda7df": "vegetation"
  },
  "instances": [
          {
            "_id": "8037614b-b5b9-420b-8e82-d601b1a7f276",
            "color": "#00c537",
            "index": 1,
            "value": "car # 1",
            "class_id": "f0443067-b6a5-4eae-a743-c967d606bb01",
            "attributes": []
          },
          {
            "_id": "bc3a8010-82cc-40cc-bac0-9a1511b5ea0c",
            "color": "#fcbe92",
            "index": 2,
            "value": "car # 2",
            "class_id": "f0443067-b6a5-4eae-a743-c967d606bb01",
            "attributes": []
          },
          {
            "_id": "0037614b-b5b9-420b-8e82-d601b1a7f276",
            "color": "#01d9fc",
            "index": 1,
            "value": "pedestrian # 1",
            "class_id": "00443067-b6a5-4eae-a743-c967d606bb01",
            "attributes": []
          },
          {
            "_id": "1c3a8010-82cc-40cc-bac0-9a1511b5ea0c",
            "color": "#fac1c2",
            "index": 2,
            "value": "pedestrian # 2",
            "class_id": "00443067-b6a5-4eae-a743-c967d606bb01",
            "attributes": []
          },
          {
            "_id": "037614b-b5b9-420b-8e82-d601b1a7f276",
            "color": "#fb0379",
            "index": 3,
            "value": "pedestrian # 3",
            "class_id": "00443067-b6a5-4eae-a743-c967d606bb01",
            "attributes": []
          },
          {
            "_id": "7c3a8010-82cc-40cc-bac0-9a1511b5ea0c",
            "color": "#fda7df",
            "index": 0,
            "value": "vegetation",
            "class_id": "4443067-b6a5-4eae-a743-c967d606bb01",
            "attributes": []
          }
          ],
  "url": "https://playment-data-uploads.s3.ap-south-1.amazonaws.com/clients/e81bddc9-e39c-4a7f-bef4-caee6f757009/projects/6f5ed111-1a46-4e06-8d72-c0dec50ac0b7/batch_export_result/0f0abfb5-4c5f-4838-a89e-92d5234b0b09/576d8391-0ce5-4cd4-969a-f3806e1cf2f4/source.png"
}
```

{% endtab %}
{% endtabs %}

To access the PNG mask (`url` in the result object), you will need to use the GET Attachment API.

The mask is a PNG file with four 8-bit channels. The first 3 channels are R, G & B respectively. These can be used to obtain a hex code for any pixel, which then maps to a class or instance based on the`legend` object.

![](https://1898243238-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MAyflu2a3TSnjJox7Sw%2F-MSbKYgHH1z-_5__K0ak%2F-MSbMASFRkGxrI9VPUQX%2Fsource%20\(1\).png?alt=media\&token=60d07acc-3743-461d-a627-c94e8ebac270)


# Video Segmentation

Here's a short example to understand how to create a video segmentation job and export the results once the job has been labeled.


# Create a job

## A JOB

<mark style="color:green;">`POST`</mark> `https://api.playment.io/v1/projects/:project_id/jobs`

#### Path Parameters

| Name                                          | Type   | Description                                           |
| --------------------------------------------- | ------ | ----------------------------------------------------- |
| project\_id<mark style="color:red;">\*</mark> | string | ID of the project in which you want to create the job |

#### Headers

| Name                                        | Type   | Description                |
| ------------------------------------------- | ------ | -------------------------- |
| x-api-key<mark style="color:red;">\*</mark> | string | API key for authentication |

#### Request Body

| Name                                             | Type   | Description                                                                                                                                                                                                                                                                                                            |
| ------------------------------------------------ | ------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| batch\_id<mark style="color:red;">\*</mark>      | string | <p>A batch is a way to organise multiple jobs under one <code>batch\_id</code>.  You can create new batches from the dashboard or by using the batch creation API.<br><br>If <code>batch\_id</code> is left empty or the key is not present, the job is created in the <code>Default batch</code> in your project.</p> |
| data<mark style="color:red;">\*</mark>           | object | The `data` object contains all the information and attachments required to label a job. The `data` object is defined below                                                                                                                                                                                             |
| work\_flow\_id<mark style="color:red;">\*</mark> | string | The ID of the workflow inside which you want to create the job                                                                                                                                                                                                                                                         |
| reference\_id<mark style="color:red;">\*</mark>  | string | The unique identifier of the job                                                                                                                                                                                                                                                                                       |

{% tabs %}
{% tab title="200: OK " %}

```javascript
{
  "data": {
    "job_id": UUID,
    "reference_id": "001",
    "work_flow_id": UUID
  },
  "success": true
}
```

{% endtab %}
{% endtabs %}

## Payload

```json
{
    "reference_id": "001",
    "data": {
        "video_data": {
            "frames": [
                {
                    "frame_id": "frame1",
                    "src": "https://s3.aws.com/600x400/000/fff.jpg&text=Dummy+Image+1"
                },
                {
                    "frame_id": "frame2",
                    "src": "https://s3.aws.com/600x400/000/fff.jpg&text=Dummy+Image+2"
                }
            ]
        },
        "reference_data": {
            "raster": {
                "images": [
                    {
                        "frame_id": "frame1",
                        "data": [
                            {
                                "label": "camera 1",
                                "image_url": "https://s3.aws.com/600x400/000/fff.jpg&text=Dummy+Image+1"
                            },
                            {
                                "label": "camera 2",
                                "image_url": "https://s3.aws.com/600x400/000/fff.jpg&text=Dummy+Image+1"
                            }
                        ]
                    },
                    {
                        "frame_id": "frame2",
                        "data": [
                            {
                                "label": "camera 1",
                                "image_url": "https://s3.aws.com/600x400/000/fff.jpg&text=Dummy+Image+1"
                            },
                            {
                                "label": "camera 2",
                                "image_url": "https://s3.aws.com/600x400/000/fff.jpg&text=Dummy+Image+1"
                            }
                        ]
                    }
                ]
            }
        }
    },
    "work_flow_id": <UUID>,
    "batch_id": <UUID>
}
```

## Payload Definition

| Key                      | Type     | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| ------------------------ | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `data.video_data.frames` | `array`  | <p>This contains an array of objects, with each object containing two properties: <br><code>frame\_id</code> - Unique identifier for the frame<br><code>src</code> - URL of the image</p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| `data.reference_data`    | `Object` | <p>The <code>reference\_data</code> object contains an additional list of images that can be used as a reference while annotating the primary image.</p><p>This is an <code>optional</code> key based on your requirement. </p><p></p><p><code>data.reference\_data.raster.images</code> is an array of objects, each containing two properties: <code>frame\_id</code> and <code>data.</code></p><p></p><p><code>frame\_id</code> is a unique identifier for the frame, which will be used to map reference image(s) with the main image.</p><p></p><p>Each element of the <code>data</code> array contains two properties: <code>label</code> and <code>image\_url</code>.</p><p></p><p><code>image\_url</code> - URL of the image</p><p><code>label</code>- Name of the image. </p> |


# Get job results

## JOB RESULT

<mark style="color:blue;">`GET`</mark> `https://api.playment.io/v1/projects/:project_id/jobs/:job_id`

This endpoint allows you to get the annotations created on a job.

#### Path Parameters

| Name        | Type   | Description                                                                              |
| ----------- | ------ | ---------------------------------------------------------------------------------------- |
| job\_id     | string | ID of the job. You would have received this ID in the response when you created the job. |
| project\_id | string | ID of the project where the job was created                                              |

#### Headers

| Name      | Type   | Description                |
| --------- | ------ | -------------------------- |
| x-api-key | string | API key for authentication |

{% tabs %}
{% tab title="200 Job results successfully retrieved." %}

```javascript
{
    "data": {
        "project_id": "af329e2b-08e8-4e52-bdb7-79277364030d",
        "reference_id": "videosegdemo",
        "job_id": "ec862ac3-55df-425f-ab06-fab4eb933116",
        "batch_id": "3952b8a4-afd5-4f51-adf6-e18a2d2af97d",
        "status": "completed",
        "work_flow_id": "2b2446ad-9c08-43c5-ba62-9a756ef87dd0",
        "tag": "2b2446ad-9c08-43c5-ba62-9a756ef87dd0",
        "priority_weight": 5,
        "result": "http://d5g2iurv6azza.cloudfront.net/cl/76a5e6d0-0c88-426c-8fc6-c28ca79221ad/pr/af329e2b-08e8-4e52-bdb7-79277364030d/bt/3952b8a4-afd5-4f51-adf6-e18a2d2af97d/jb/ec862ac3-55df-425f-ab06-fab4eb933116/submission_result/ec862ac3-55df-425f-ab06-fab4eb933116.json"
    },
    "success": true
}
```

{% endtab %}
{% endtabs %}

## ATTACHMENT

<mark style="color:blue;">`GET`</mark> `https://api.playment.io/v1/attachments?url=:result_url`

The *result\_url* (`data.result`) returned by the GET Job result API is a private URL (Well, it's public till 15th July 2021, after which we'll enforce it to be private). You need to use this Attachment access API to securely fetch the results. Please refer to the Attachment Access API document for more detail.

#### Path Parameters

| Name        | Type   | Description                                   |
| ----------- | ------ | --------------------------------------------- |
| result\_url | string | Result URL returned by the GET job result API |

#### Headers

| Name      | Type   | Description                |
| --------- | ------ | -------------------------- |
| x-api-key | string | API key for authentication |

{% tabs %}
{% tab title="200 " %}

```json
{
  "data": {
    "annotation_data": {
      "annotations": [
        {
          "_id": "c2d1b627-2af8-49ae-b4ab-0c94571e2b2d",
          "attributes": [],
          "frame_id": "frame1",
          "track_id": "3f05676e-c959-43d4-a95b-a1168caabe35"
        },
        {
          "_id": "ae41fc43-a6f5-4c29-ab3b-70a294aaac5d",
          "attributes": [],
          "frame_id": "frame2",
          "track_id": "3f05676e-c959-43d4-a95b-a1168caabe35"
        }
      ],
      "frames": [
        {
          "_id": "frame1"
        },
        {
          "_id": "frame2"
        }
      ],
      "legend": {
        "#090575": "Ground",
        "#127a8e": "Vegetation",
        "#241b51": "Person # 1",
        "#60b7e0": "Person",
        "#d32142": "Car",
        "#db415d": "Debris",
        "#dd900b": "Misc"
      },
      "masks": [
        {
          "_id": "",
          "frame_id": "frame1",
          "mask_url": "http://d5g2iurv6azza.cloudfront.net/cl/76a5e6d0-0c88-426c-8fc6-c28ca79221ad/pr/af329e2b-08e8-4e52-bdb7-79277364030d/bt/3952b8a4-afd5-4f51-adf6-e18a2d2af97d/jb/ec862ac3-55df-425f-ab06-fab4eb933116/qs/b583a64f-8765-44df-bb7e-78835ea5a7ef/raster_mask/290a0c90-e6b5-4610-8dfe-3fb8880e2b1f.png"
        },
        {
          "_id": "",
          "frame_id": "frame2",
          "mask_url": "http://d5g2iurv6azza.cloudfront.net/cl/76a5e6d0-0c88-426c-8fc6-c28ca79221ad/pr/af329e2b-08e8-4e52-bdb7-79277364030d/bt/3952b8a4-afd5-4f51-adf6-e18a2d2af97d/jb/ec862ac3-55df-425f-ab06-fab4eb933116/qs/b583a64f-8765-44df-bb7e-78835ea5a7ef/raster_mask/c07e1b89-c308-4482-acab-af1e3953984e.png"
        }
      ],
      "tracks": [
        {
          "_id": "3f05676e-c959-43d4-a95b-a1168caabe35",
          "class_id": "631aab77-e50d-412f-aa0c-e7e1361f40f9",
          "class_label": "Person",
          "color": "#241b51",
          "value": "Person # 1"
        }
      ]
    },
    "video_data": {
      "frames": [
        {
          "_id": "00000000-0000-0000-0000-000000000000",
          "frame_id": "frame1",
          "meta_data": null,
          "ref_id": "",
          "src": "http://d5g2iurv6azza.cloudfront.net/cl/76a5e6d0-0c88-426c-8fc6-c28ca79221ad/pr/af329e2b-08e8-4e52-bdb7-79277364030d/bt/3952b8a4-afd5-4f51-adf6-e18a2d2af97d/jb/ec862ac3-55df-425f-ab06-fab4eb933116/validated_data/4c60068d-b64a-4336-ad20-91f4d22600a4",
          "src_original": "https://playment-data-uploads.s3.ap-south-1.amazonaws.com/clients/cde4d0fb-63c3-43f0-bb46-a11ebc6d4455/projects/a6eb8c75-bdf0-4e5e-bbb3-b140db8350ac/batch_upload_data/64513983-a554-47f1-ae38-50390ea21c5c/ezgif-4-61dbf91b9c12-jpg/ezgif-frame-001.jpg"
        },
        {
          "_id": "00000000-0000-0000-0000-000000000000",
          "frame_id": "frame2",
          "meta_data": null,
          "ref_id": "",
          "src": "http://d5g2iurv6azza.cloudfront.net/cl/76a5e6d0-0c88-426c-8fc6-c28ca79221ad/pr/af329e2b-08e8-4e52-bdb7-79277364030d/bt/3952b8a4-afd5-4f51-adf6-e18a2d2af97d/jb/ec862ac3-55df-425f-ab06-fab4eb933116/validated_data/7d22c0e6-ad1b-4293-b4e6-99f877b2a70e",
          "src_original": "https://playment-data-uploads.s3.ap-south-1.amazonaws.com/clients/cde4d0fb-63c3-43f0-bb46-a11ebc6d4455/projects/a6eb8c75-bdf0-4e5e-bbb3-b140db8350ac/batch_upload_data/64513983-a554-47f1-ae38-50390ea21c5c/ezgif-4-61dbf91b9c12-jpg/ezgif-frame-002.jpg"
        }
      ]
    }
  },
  "frame1": "http://d5g2iurv6azza.cloudfront.net/cl/76a5e6d0-0c88-426c-8fc6-c28ca79221ad/pr/af329e2b-08e8-4e52-bdb7-79277364030d/bt/3952b8a4-afd5-4f51-adf6-e18a2d2af97d/jb/ec862ac3-55df-425f-ab06-fab4eb933116/batch_export_result/videosegdemo.frame1.png",
  "frame2": "http://d5g2iurv6azza.cloudfront.net/cl/76a5e6d0-0c88-426c-8fc6-c28ca79221ad/pr/af329e2b-08e8-4e52-bdb7-79277364030d/bt/3952b8a4-afd5-4f51-adf6-e18a2d2af97d/jb/ec862ac3-55df-425f-ab06-fab4eb933116/batch_export_result/videosegdemo.frame2.png"
}
```

{% endtab %}
{% endtabs %}

## Result Object

```json
{
  "data": {
    "annotation_data": {
      "annotations": [],
      "frames": [],
      "legend": {},
      "masks": [],
      "tracks": []
    },
    "video_data": {
      "frames": []
    }
  },
}
```

The `data.annotations_data.annotations` list contains objects where each object is an annotation. You can check the data structures in detail below:

{% tabs %}
{% tab title="annotations" %}

```json
"attributes": [], 
"frame_id": "frame1", 
"track_id": "3f05676e-c959-43d4-a95b-a1168caabe35"
```

{% endtab %}

{% tab title="legend" %}

```json
"#090575": "Ground", 
"#127a8e": "Vegetation", 
"#241b51": "Person # 1", 
"#d32142": "Car"
```

{% endtab %}

{% tab title="masks" %}
{% code overflow="wrap" %}

```json
"frame_id": "frame1", 
"mask_url": "http://d5g2iurv6azza.cloudfront.net/cl/76a5e6d0-0c88-426c-8fc6-c28ca79221ad/pr/af329e2b-08e8-4e52-bdb7-79277364030d/bt/3952b8a4-afd5-4f51-adf6-e18a2d2af97d/jb/ec862ac3-55df-425f-ab06-fab4eb933116/qs/b583a64f-8765-44df-bb7e-78835ea5a7ef/raster_mask/290a0c90-e6b5-4610-8dfe-3fb8880e2b1f.png"
```

{% endcode %}
{% endtab %}

{% tab title="frames" %}

```json
"_id": "frame1"
```

{% endtab %}

{% tab title="tracks" %}

```json
"_id": "3f05676e-c959-43d4-a95b-a1168caabe35", 
"class_id": "631aab77-e50d-412f-aa0c-e7e1361f40f9", 
"class_label": "Person", 
"color": "#241b51", 
"value": "Person # 1"
```

{% endtab %}
{% endtabs %}

| Key        | Description                                                                          |
| ---------- | ------------------------------------------------------------------------------------ |
| `frame_id` | A foreign key to join with the frame object in `sensor_data.frames`                  |
| `track_id` | All annotations across frames, belonging to the same object have a common `track_id` |

To access the PNG mask (`url` in the result object), you will need to use the GET Attachment API.

The mask is a PNG file with four 8-bit channels. The first 3 channels are R, G & B respectively. These can be used to obtain a hex code for any pixel, which then maps to a class or instance based on the`legend` object.

![](https://1898243238-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MAyflu2a3TSnjJox7Sw%2F-MSbKYgHH1z-_5__K0ak%2F-MSbMASFRkGxrI9VPUQX%2Fsource%20\(1\).png?alt=media\&token=60d07acc-3743-461d-a627-c94e8ebac270)


# Video Annotation

Here's a short example to understand how to create an video annotation job and export the results once the job has been labeled.

{% hint style="warning" %}
Although we call it *video annotation* for ease of understanding, we don't directly support video file formats like `MP4` or `AVI`. Each video annotation job needs to be a sequence of images.
{% endhint %}

{% hint style="info" %}
If you have video files, we recommend using a program like [this](https://stackoverflow.com/a/33399711) to split videos to frames&#x20;
{% endhint %}

{% content-ref url="/pages/-MSbNOyci8A5RdO7fnDH" %}
[Create a job](/video-annotation/create-a-job)
{% endcontent-ref %}


# Create a job

## A JOB

<mark style="color:green;">`POST`</mark> `https://api.playment.io/v1/projects/:project_id/jobs`

This endpoint allows you to create a job

#### Path Parameters

| Name        | Type   | Description                                           |
| ----------- | ------ | ----------------------------------------------------- |
| project\_id | string | ID of the project in which you want to create the job |

#### Headers

| Name      | Type   | Description                |
| --------- | ------ | -------------------------- |
| x-api-key | string | API key for authentication |

#### Request Body

| Name           | Type   | Description                                                                                                                                                                                                                                                                                                            |
| -------------- | ------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| batch\_id      | string | <p>A batch is a way to organize multiple jobs under one <code>batch\_id</code>.  You can create new batches from the dashboard or by using the batch creation API.<br><br>If <code>batch\_id</code> is left empty or the key is not present, the job is created in the <code>Default batch</code> in your project.</p> |
| work\_flow\_id | string | The ID of the workflow inside which you want to create the job                                                                                                                                                                                                                                                         |
| data           | object | The `data` object contains all the information and attachments required to label a job. The `data` object is defined below                                                                                                                                                                                             |
| reference\_id  | string | The unique identifier of the job                                                                                                                                                                                                                                                                                       |

{% tabs %}
{% tab title="200 " %}

```
{
  "data": {
    "job_id": "3f3e8675-ca69-46d7-aa34-96f90fcbb732",
    "reference_id": "001",
    "work_flow_id": "2aae1234-acac-1234-eeff-12a22a237bbc"
  },
  "success": true
}
```

{% endtab %}
{% endtabs %}

## Payload

```javascript
{
    "reference_id": "001",
    "data": {
        "video_data": {
            "frames": [
                {
                    "frame_id": "frame1",
                    "src": "https://s3.aws.com/600x400/000/fff.jpg&text=Dummy+Image+1"
                },
                {
                    "frame_id": "frame2",
                    "src": "https://s3.aws.com/600x400/000/fff.jpg&text=Dummy+Image+2"
                }
            ]
        },
        "reference_data": {
            "vector": {
                "images": [
                    {
                        "frame_id": "frame1",
                        "data": [
                            {
                                "label": "camera 1",
                                "image_url": "https://s3.aws.com/600x400/000/fff.jpg&text=Dummy+Image+1"
                            },
                            {
                                "label": "camera 2",
                                "image_url": "https://s3.aws.com/600x400/000/fff.jpg&text=Dummy+Image+1"
                            }
                        ]
                    },
                    {
                        "frame_id": "frame2",
                        "data": [
                            {
                                "label": "camera 1",
                                "image_url": "https://s3.aws.com/600x400/000/fff.jpg&text=Dummy+Image+1"
                            },
                            {
                                "label": "camera 2",
                                "image_url": "https://s3.aws.com/600x400/000/fff.jpg&text=Dummy+Image+1"
                            }
                        ]
                    }
                ]
            }
        }
    },
     "work_flow_id":"2aae1234-acac-1234-eeff-12a22a237bbc"
}
```

## Payload Definition

| Key                      | Type     | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| ------------------------ | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `data.video_data.frames` | `array`  | <p>This contains an array of objects, with each object containing two properties:<br><code>frame\_id</code> - Unique identifier for the frame.<br><code>src</code> - URL of the image.</p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| `data.reference_data`    | `Object` | <p>The <code>reference\_data</code> object contains an additional list of images that can be used as a reference while annotating the primary image.<br>This is an <code>optional</code> key based on your requirement.<br><code>data.reference\_data.vector.images</code> is an array of objects, each containing two properties: <code>frame\_id</code> and <code>data</code>.<br><code>frame\_id</code> is a unique identifier for the frame, which will be used to map reference image(s) with the main image.<br>Each element of the <code>data</code> array contains two properties: label and image\_url.<br><code>image\_url</code> - URL of the image.<br><code>label</code>- Name of the image.</p> |

### Code Example

{% tabs %}
{% tab title="Python" %}

```python
import requests
import json

"""
Details for creating JOBS,
project_id  ->> ID of project in which the job will be created
x_api_key   ->> API key for authentication 
workflow_id ->> The workflow in which the job will be created
batch_id    ->> The batch in which job will be created
"""

# Additional helper function to create a batch
def create_batch(BATCH_NAME):
    base_url = f"https://api.playment.io/v1/projects/{PROJECT_ID}/batch"
    DATA = {"name":BATCH_NAME}
    response = requests.post(base_url, headers={'x-api-key': CLIENT_KEY}, json=DATA)
    response_data = response.json()
    if response.status_code >= 500:
        raise Exception(f"Something went wrong at Playment's end {response.status_code}")
    if 400 <= response.status_code < 500:
        raise Exception(f"{response_data['error']['message']} {response.status_code}")
    print(response_data)
    return response_data
    
#method that can be used to call the job creation api
def create_job(project_id, data, x_api_key):
    base_url = "https://api.playment.io/v1/projects/{}/jobs".format(project_id)
    headers = {'x-api-key': x_api_key}
    response = requests.post(base_url, headers=headers, json=data)
    
    print(response.json())
    if response.status_code >= 500:
        raise Exception(response.text)
    if 400 <= response.status_code < 500:
        raise Exception(response.text)
    return response.json()

if __name__ == "__main__":
    #list of frames in a single job
 
    frames = ["https://example.com/image_url_1","https://example.com/image_url_2","https://example.com/image_url_3"]
    
    #reference_id should be unique for each job
    reference_id= "job1"

    project_id = ''
    x_api_key = ''
    workflow_id = ''
    batch_id = ''
    

    video_data = {'frames' : []}

    i=0
    for frame_url in frames:
        i=i+1
        frame_id = "frame"+str(i)      
        frame_obj = {'src':frame_url,'frame_id':frame_id}
        video_data['frames'].append(frame_obj)
		    job_data = {
		        'reference_id': reference_id,
		        'workflow_id': workflow_id,
		        'batch_id': batch_id,
		        'data': {
		            'video_data': video_data,
		            'reference_data': {
		                'vector': {
		                    'images': [
		                        {
		                            'frame_id': 'frame1',
		                            'data': [
		                                {
		                                    'label': 'camera 1',
		                                    'image_url': 'https://s3.aws.com/600x400/000/fff.jpg&text=Dummy+Image+1'
		                                },
		                                {
		                                    'label': 'camera 2',
		                                    'image_url': 'https://s3.aws.com/600x400/000/fff.jpg&text=Dummy+Image+1'
		                                }
		                            ]
		                        },
		                        {
		                            'frame_id': 'frame2',
		                            'data': [
		                                {
		                                    'label': 'camera 1',
		                                    'image_url': 'https://s3.aws.com/600x400/000/fff.jpg&text=Dummy+Image+2'
		                                },
		                                {
		                                    'label': 'camera 2',
		                                    'image_url': 'https://s3.aws.com/600x400/000/fff.jpg&text=Dummy+Image+2'
		                                }
		                            ]
		                        }
		                    ]
		                }
		            }
		        }
		    }
		    

    
    response = create_job(project_id=project_id, data=job_data, x_api_key= x_api_key)
    print(response)
    
```

{% endtab %}
{% endtabs %}

## Creating jobs with pre-labeled data

If you have data which has been labeled previously by an ML model or by human labelers, you can create jobs with such labels already created. To do this, you need to send the annotation data in the `data.maker_response` key in the payload. The annotation data needs to be in our annotation format.

Here's an example

```javascript
{  
   "reference_id":"001",
   "data":{
     "video_data": {
      "frames": [...]
     },
     "maker_response" : {
        "video2d": {
           "data": {
              "annotations": []
           }
        }
     }
   },
   "work_flow_id":"2aae1234-acac-1234-eeff-12a22a237bbc"
}
```

The `data.maker_response.video_2d.data.annotations` list contains objects, where each object is a *tracker*. A tracker tracks an object across frames. The `frames` key in the tracker object maps each *annotation object* in the tracker to the `frame_id` it belongs to.&#x20;

```javascript
{
  "_id": "",
  "type": "rectangle", // rectangle/polygon/line/cuboid/landmark
  "label": "Cat",
  "frames" : {
    "frame001" : {<annotation_object>}
  }
}
```

You can check the structure for various `annotation_object` below:

{% tabs %}
{% tab title="Rectangles" %}

```javascript
{
  "_id": "0e6d895e-2484-439a-b62b-d8a0afb3d190",
  "label": "".
  "attributes": {
    "pose": {
      "value": "standing"
    },
    "breed": {
      "value": "Persian"
    }
  }
  "coordinates": [
    {"x": 0.00398, "y": 0.00558},
    {"x": 0.05404, "y": 0.00558},
    {"x": 0.05404, "y": 0.09096},
    {"x": 0.00398, "y": 0.09096}
  ]
}
```

{% endtab %}

{% tab title="Polygon" %}

```javascript
{
  "_id": "8f8897ad-e07b-4e55-9dbe-61f6b9df85c5",
  "label": "face_mask",
  "attributes": {
    "covers_nose": {
      "value": "Yes"
    },
  }
  "points": {
    "p1": {"x": 0.286774, "y": 0.892502},
    "p2": {"x": 0.385849, "y": 0.576888},
    "p3": {"x": 0.426721, "y": 0.469081},
    "p4": {"x": 0.288623, "y": 0.253878},
    "p5": {"x": 0.148623, "y": 0.353878}
  },
  "edges": {
    "e1": ["p1", "p2"],
    "e2": ["p2", "p3"],
    "e3": ["p3", "p4"],
    "e4": ["p4", "p4"],
    "e5": ["p5", "p1"]
  }
}
```

{% endtab %}

{% tab title="Line" %}

```javascript
{
  "_id": "8f8897ad-e07b-4e55-9dbe-61f6b9df85c5",
  "label": "lane_divider",
  "attributes": {
    "raised": {
      "value": "Yes"
    },
  }
  "points": {
    "p1": {"x": 0.286774, "y": 0.892502},
    "p2": {"x": 0.285849, "y": 0.876888},
    "p3": {"x": 0.286774, "y": 0.869081},
    "p4": {"x": 0.288623, "y": 0.853878}
  }
}
```

{% endtab %}

{% tab title="Cuboid" %}

```javascript
{
  "_id": "8f8897ad-e07b-4e55-9dbe-61f6b9df85c5",
  "label": "Car",
  "attributes" : {
    "faces_visible": {
      "value": ["right","back"]
    }
  },
  "points": {
    "p1": {"x": 0.17,"y": 0.58},
    "p2": {"x": 0.26,"y": 0.58},
    "p3": {"x": 0.26,"y": 0.49},
    "p4": {"x": 0.17,"y": 0.49},
    "p5": {"x": 0.24,"y": 0.51},
    "p6": {"x": 0.35,"y": 0.52},
    "p7": {"x": 0.35,"y": 0.36},
    "p8": {"x": 0.25,"y": 0.37}
  },
  "front": {
    "coordinates": ["p1","p2","p3","p4"]
  },
  "side": {
    "coordinates": ["p2","p3","p5","p6"]
  },
  "back": {
    "coordinates": ["p7","p8","p5","p6"]
  }
}
```

{% endtab %}

{% tab title="Landmark" %}

```javascript
{
  "_id": "e7e3353f-2ffe-432a-a14f-9cb9a6f4b735",
  "label": "nose",
  "attributes": {
    "visible": {
      "value": "Partially"
    },
  }
  "points": {
    "p1": { "x": 0.17, "y": 0.58, "label": 1 },
    "p2": { "x": 0.26, "y": 0.63, "label": 2 },
    "p3": { "x": 0.27, "y": 0.63, "label": 3 },
    "p4": { "x": 0.29, "y": 0.59, "label": 4 },
    "p5": { "x": 0.25, "y": 0.46, "label": 5 },
    "p6": { "x": 0.22, "y": 0.42, "label": 6 }
  }
}
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
In our annotation output, the **x and y coordinates are normalised** to ensure consistency across different image sizes. Normalisation is crucial for accurately representing object positions relative to the image dimensions.

**X and Y Coordinates:**

* **X Coordinate:**
  * Normalised x coordinates ($$Xnorm​$$) are calculated using the formula: \
    $$Xnorm = Xraw / Image Width$$
  * The result ranges from 0.0 to 1.0, where 0.0(Origin) corresponds to the leftmost edge of the image, and 1.0 corresponds to the rightmost edge.
* **Y Coordinate:**
  * Normalised y coordinates ($$Ynorm​$$) are calculated using the formula: \
    $$Ynorm = Yraw / Image Height$$
  * The result ranges from 0.0 to 1.0, where 0.0(Origin) corresponds to the topmost edge of the image, and 1.0 corresponds to the bottommost edge.
    {% endhint %}


# Get job results

## JOB RESULT

<mark style="color:blue;">`GET`</mark> `https://api.playment.io/v1/projects/:project_id/jobs/:job_id`

This endpoint allows you to get the annotations created on a job.

#### Path Parameters

| Name        | Type   | Description                                                                              |
| ----------- | ------ | ---------------------------------------------------------------------------------------- |
| job\_id     | string | ID of the job. You would have received this ID in the response when you created the job. |
| project\_id | string | ID of the project where the job was created                                              |

#### Headers

| Name      | Type   | Description                |
| --------- | ------ | -------------------------- |
| x-api-key | string | API key for authentication |

{% tabs %}
{% tab title="200 Job results successfully retrieved." %}

```javascript
{
    "data": {
        "project_id": "905ea3ee-6f62-4bb7-8c31-471e486d9202",
        "reference_id": "001",
        "job_id": "3f3e8675-ca69-46d7-aa34-96f90fcbb732",
        "batch_id": "468b6ae3-e98d-4d08-9427-b6e7a016054c",
        "status": "completed",
        "work_flow_id": "51bb440c-f0ed-4286-8984-ea399cbc1f9w",
        "priority_weight": 5,
        "tag": "2aae1234-acac-1234-eeff-12a22a237bbc", //tag is the workflow_id for the job  
        "result": "https://playment-data-uploads.s3.ap-south-1.amazonaws.com/sample-result.json"
    },
    "success": true
}
```

{% endtab %}
{% endtabs %}

## ATTACHMENT

<mark style="color:blue;">`GET`</mark> `https://api.playment.io/v1/attachments?url=:result_url`

The *result\_url* (`data.result`) returned by the GET Job result API is a private URL (Well, it's public till 15th July 2021, after which we'll enforce it to be private). You need to use this Attachment access API to securely fetch the results. Please refer to the Attachment Access API document for more detail.

#### Path Parameters

| Name        | Type   | Description                                   |
| ----------- | ------ | --------------------------------------------- |
| result\_url | string | Result URL returned by the GET job result API |

#### Headers

| Name      | Type   | Description                |
| --------- | ------ | -------------------------- |
| x-api-key | string | API key for authentication |

{% tabs %}
{% tab title="200 " %}

```
The API will redirect to a signed URL of the attachment
```

{% endtab %}
{% endtabs %}

## Result Object

```javascript
{
  "data": {
    "annotation_data": {
      "annotations": [] 
    },
    "video_data": {
      "frames": [] //This is the same list you sent while creating the job
    }
  }
}
```

The annotations list contains objects, where each object is a *tracker*. A tracker tracks an object across frames. The `frames` key in the tracker object maps each *annotation object* in the tracker to the `frame_id` it belongs to.&#x20;

```javascript
{
  "_id": "",
  "type": "rectangle", // rectangle/polygon/line/cuboid/landmark
  "label": "",
  "frames" : {
    "frame001" : {<annotation_object>}
  }
}
```

You can check the data structures for the various `annotation objects` below:&#x20;

{% tabs %}
{% tab title="Rectangle" %}

```javascript
{
  "_id": "0e6d895e-2484-439a-b62b-d8a0afb3d190",
  "label": "Cat".
  "attributes": {
    "pose": {
      "value": "standing"
    },
    "breed": {
      "value": "Persian"
    }
  }
  "coordinates": [
    {"x": 0.00398, "y": 0.00558},
    {"x": 0.05404, "y": 0.00558},
    {"x": 0.05404, "y": 0.09096},
    {"x": 0.00398, "y": 0.09096}
  ]
}
```

{% endtab %}

{% tab title="Polygon" %}

```javascript
{
  "_id": "8f8897ad-e07b-4e55-9dbe-61f6b9df85c5",
  "label": "face_mask",
  "attributes": {
    "covers_nose": {
      "value": "Yes"
    },
  }
  "points": {
    "p1": {"x": 0.286774, "y": 0.892502},
    "p2": {"x": 0.385849, "y": 0.576888},
    "p3": {"x": 0.426721, "y": 0.469081},
    "p4": {"x": 0.288623, "y": 0.253878},
    "p5": {"x": 0.148623, "y": 0.353878}
  },
  "edges": {
    "e1": ["p1", "p2"],
    "e2": ["p2", "p3"],
    "e3": ["p3", "p4"],
    "e4": ["p4", "p4"],
    "e5": ["p5", "p1"]
  }
}
```

{% endtab %}

{% tab title="Line" %}

```javascript
{
  "_id": "8f8897ad-e07b-4e55-9dbe-61f6b9df85c5",
  "label": "lane_divider",
  "attributes": {
    "raised": {
      "value": "Yes"
    },
  }
  "points": {
    "p1": {"x": 0.286774, "y": 0.892502},
    "p2": {"x": 0.285849, "y": 0.876888},
    "p3": {"x": 0.286774, "y": 0.869081},
    "p4": {"x": 0.288623, "y": 0.853878}
  }
}
```

{% endtab %}

{% tab title="Cuboid" %}

```javascript
{
  "_id": "8f8897ad-e07b-4e55-9dbe-61f6b9df85c5",
  "label": "Car",
  "attributes" : {
    "faces_visible": {
      "value": ["right","back"]
    }
  },
  "points": {
    "p1": {"x": 0.17,"y": 0.58},
    "p2": {"x": 0.26,"y": 0.58},
    "p3": {"x": 0.26,"y": 0.49},
    "p4": {"x": 0.17,"y": 0.49},
    "p5": {"x": 0.24,"y": 0.51},
    "p6": {"x": 0.35,"y": 0.52},
    "p7": {"x": 0.35,"y": 0.36},
    "p8": {"x": 0.25,"y": 0.37}
  },
  "front": {
    "coordinates": ["p1","p2","p3","p4"]
  },
  "side": {
    "coordinates": ["p2","p3","p5","p6"]
  },
  "back": {
    "coordinates": ["p7","p8","p5","p6"]
  }
}
```

{% endtab %}

{% tab title="Landmark" %}

```javascript
{
  "_id": "e7e3353f-2ffe-432a-a14f-9cb9a6f4b735",
  "label": "nose",
  "attributes": {
    "visible": {
      "value": "Partially"
    },
  }
  "points": {
    "p1": { "x": 0.17, "y": 0.58, "label": 1 },
    "p2": { "x": 0.26, "y": 0.63, "label": 2 },
    "p3": { "x": 0.27, "y": 0.63, "label": 3 },
    "p4": { "x": 0.29, "y": 0.59, "label": 4 },
    "p5": { "x": 0.25, "y": 0.46, "label": 5 },
    "p6": { "x": 0.22, "y": 0.42, "label": 6 }
  }
}
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
In our annotation output, the **x and y coordinates are normalised** to ensure consistency across different image sizes. Normalisation is crucial for accurately representing object positions relative to the image dimensions.

**X and Y Coordinates:**

* **X Coordinate:**
  * Normalised x coordinates ($$Xnorm​$$) are calculated using the formula: \
    $$Xnorm = Xraw / Image Width$$
  * The result ranges from 0.0 to 1.0, where 0.0(Origin) corresponds to the leftmost edge of the image, and 1.0 corresponds to the rightmost edge.
* **Y Coordinate:**
  * Normalised y coordinates ($$Ynorm​$$) are calculated using the formula: \
    $$Ynorm = Yraw / Image Height$$
  * The result ranges from 0.0 to 1.0, where 0.0(Origin) corresponds to the topmost edge of the image, and 1.0 corresponds to the bottommost edge.
    {% endhint %}


# 3D Point Cloud Annotation

In this section, We have added some examples to understand how to create an 3D point cloud annotation job and export the results once the job has been labeled.

There are two types of point cloud annotation tasks supported in GT Studio:

1. **3D Bounding Box:** 3D bounding boxes on point clouds + projected cuboids on image
2. **2D-3D Linking:** 3D bounding boxes on point clouds + linked 2D bounding boxes on images

GT Studio supports multi-sensor setups, i.e. where you have a point cloud along with images from multiple cameras. If you provide calibration information (poses of each sensor and camera intrinsic), the tool will automatically project annotations from the 3D space to the cameras.

{% hint style="warning" %}
We support 3D point cloud annotations in our enterprise plan as a fully managed service offering. Please [contact us](https://playment.io/sign-up) if you are interested in 3D point cloud annotations.
{% endhint %}


# Create a job

You can send your data to us through either of the following channels

1. API (recommended)
2. Sharing a cloud storage bucket

The data could be a collection of frames or a collection of sequences. A unit of work is either a single frame or a single sequence based on your requirement. The API will have to be called for each unit of work.

Following Json template gives an idea of the payload the API is expecting.

The payload is organised as follows

1. Each request is made of frames and sensor meta data
2. Each frame can have multiple sensor data
3. For each sensor following two types of data is expected
   1. URL to the media which can be accessed by our servers
   2. Pose of the sensor for that frame. Please ensure that the sensor poses and the point cloud files are with respect to the same coordinate frame of reference.
4. In sensor meta, each sensor has to be defined and the intrinsics of the camera sensors is expected.

Note: Following values are just placeholders and actual values will be expected in the request.

## A JOB

<mark style="color:green;">`POST`</mark> `https://api.playment.io/v1/projects/:project_id/jobs`

This endpoint allows you to create a job

#### Path Parameters

| Name        | Type   | Description                                           |
| ----------- | ------ | ----------------------------------------------------- |
| project\_id | string | ID of the project in which you want to create the job |

#### Headers

| Name      | Type   | Description                |
| --------- | ------ | -------------------------- |
| x-api-key | string | API key for authentication |

#### Request Body

| Name           | Type   | Description                                                                                                                                                                                                                                                                                                            |
| -------------- | ------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| batch\_id      | string | <p>A batch is a way to organize multiple jobs under one <code>batch\_id</code>.  You can create new batches from the dashboard or by using the batch creation API.<br><br>If <code>batch\_id</code> is left empty or the key is not present, the job is created in the <code>Default batch</code> in your project.</p> |
| work\_flow\_id | string | The ID of the workflow inside which you want to create the job                                                                                                                                                                                                                                                         |
| data           | object | The `data` object contains all the information and attachments required to label a job. The `data` object is defined below                                                                                                                                                                                             |
| reference\_id  | string | The unique identifier of the job                                                                                                                                                                                                                                                                                       |

{% tabs %}
{% tab title="200 " %}

```
{
  "data": {
    "job_id": "3f3e8675-ca69-46d7-aa34-96f90fcbb732",
    "reference_id": "001",
    "work_flow_id": "2aae1234-acac-1234-eeff-12a22a237bbc"
  },
  "success": true
}
```

{% endtab %}
{% endtabs %}

## Payload

```javascript
{  
   "reference_id":"001",
   "data":{
     "apc_task" : false
     "sensor_data": {
      "frames": [
        {
          "frame_id": "frame001",
          "ego_pose" : {
            "position": {
              "x": 0,
              "y": 0,
              "z": 0
            },
            "heading": {
              "w": 1,
              "x": 0,
              "y": 0,
              "z": 0
            }
          },
          "sensors" : [
            {
              "sensor_id": "lidar",
              "data_url": "https://s3.amazonaws.com/example-bucket/lidar/frame001.pcd",
              "sensor_pose": {
                "position": {
                  "x": 0.1,
                  "y": 0.05,
                  "z": 0.4
                },
                "heading": {
                  "w": 0.847,
                  "x": -0.002,
                  "y": -0.504,
                  "z": 0.168
                }
              }
            },
            {
              "sensor_id": "cam-1",
              "data_url": "https://s3.amazonaws.com/example-bucket/cam-1/frame001.png",
              "sensor_pose": {
                "position": {
                  "x": 0.01,
                  "y": 0.1,
                  "z": 0.1
                },
                "heading": {
                  "w": 0.002,
                  "x": 0.847,
                  "y": -0.168,
                  "z": 0.504
                }
              }
            }
          ]
        },
        {
          "frame_id": "frame002",
          "ego_pose" : {
                "position": {
                  "x": 0.1,
                  "y": 0.05,
                  "z": 0.4
                },
                "heading": {
                  "w": 0.847,
                  "x": -0.002,
                  "y": -0.504,
                  "z": 0.168
                }
              },
          "sensors" : [
            {
              "sensor_id": "lidar",
              "data_url": "https://s3.amazonaws.com/example-bucket/lidar/frame002.pcd",
              "sensor_pose": {
                "position": {
                  "x": 0,
                  "y": 0,
                  "z": 0
                },
                "heading": {
                  "w": 1,
                  "x": 0,
                  "y": 0,
                  "z": 0
                }
              }
            },
            {
              "sensor_id": "cam-1",
              "data_url": "https://s3.amazonaws.com/example-bucket/cam-1/frame002.png",
              "sensor_pose": {
                "position": {
                  "x": 0.01,
                  "y": 0.1,
                  "z": 0.1
                },
                "heading": {
                  "w": 0.002,
                  "x": 0.847,
                  "y": -0.168,
                  "z": 0.504
                }
              }
            }
          ]
        }
      ],
      "sensor_meta" : [
        {
          "id": "lidar",
          "name": "lidar",
          "state": "editable",
          "modality": "lidar",
          "primary_view": true
        },
        {
          "id": "cam-1",
          "name": "cam-1",
          "state": "editable",
          "modality": "camera",
          "camera_model": "brown_conrady", 
          "primary_view": false,
          "intrinsics": {
            "cx": 600,
            "cy": 400,
            "fx": 1200,
            "fy": 800,
            "k1": 0,
            "k2": 0,
            "k3": 0,
            "k4": 0,
            "p1": 0,
            "p2": 0,
            "skew": 0,
            "scale_factor": 1
          }
        }
      ]
    }
   },
   "work_flow_id":"2aae1234-acac-1234-eeff-12a22a237bbc"
}
```

### Payload definition

| Key                                    | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |   Type   |
| -------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :------: |
| `data.sensor_data`                     | Contains lists of frames and sensor metadata                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      | `Object` |
| `data.sensor_data.sensor_meta`         | <p>Contains a list of all the sensors with each having metadata information like <br><code>id</code> : id of sensor<br><code>name</code> : name of sensor <br><code>modality</code> : lidar / camera</p><p><br>If the sensor is a camera, you can add the camera <code>intrinsic</code> values as well as the <code>camera\_model</code>. These values are used along with the sensor\_pose to create projections between sensors.</p><p></p><p><code>camera\_model</code>:  one of <code>brown\_conrady</code> , <code>fisheye</code>  or <code>cylindricalV2</code> (for cylindrical camera model).</p><p>If this key doesn't exist or is null, the tool will assume <code>brown\_conrady</code>.</p><p></p><p>The <code>intrinsics</code> object contains the following keys:</p><p><code>cx</code>: principal point x value<br><code>cy</code>: principal point y value<br><code>fx</code>: focal length in x-axis<br><code>fy</code>: focal length in y-axis<br><code>k1, k2, k3, k4, k5, k6</code>: Radial distortion coefficients<br><code>p1, p2</code>: Tangential distortion coefficients<br><code>skew</code>: camera skew coefficient<br><code>scale\_factor</code>: The factor by which the image has been downscaled (For example, scale\_factor will be 2 if the original image is twice as large as the downscaled image)</p><p></p><p>If the <code>camera\_model</code> is <code>brown\_conrady</code> then the distortion coefficients should be one of the following combinations:</p><ul><li>k1, k2, p1, p2</li><li>k1, k2, p1, p2, k3</li><li>k1, k2, p1, p2, k3, k4, k5, k6</li></ul><p></p><p>If the <code>camera\_model</code> is <code>fisheye</code> then the distortion coefficients should be the following combination:</p><ul><li>k1, k2, k3, k4</li></ul><p></p><p>If the <code>camera\_model</code> is <code>cylindricalV2</code> (for cylindrical camera model) then no distortion coefficients (k1 - k6, p1, p2) are needed or used.</p><p></p><p>The remaining coefficients can be ignored or be assigned a value of 0</p><p></p><p>OpenCV reference<a href="https://docs.opencv.org/2.4/modules/calib3d/doc/camera_calibration_and_3d_reconstruction.html">: Camera calibration and 3D reconstruction</a></p> | `Object` |
| `data.sensor_data.frames`              | List of frames, each for a particular timestamp in the order of annotation. Each having `frame_id`, `ego_pose` and `sensors`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |  `List`  |
| `data.sensor_data.frames.[i].frame_id` | Unique identifier of the particular frame                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         | `String` |
| `data.sensor_data.frames.[i].ego_pose` | <p>Contains the pose of a fixed point on the ego vehicle in the world frame of reference in the form of position (in (x, y, z)) and orientation (as quaternion (w, x, y, z))</p><p></p><p>In case the pose of the ego vehicle is available in the world frame of reference, The tool can allow annotators to mark objects as stationary and toggle APC (Aggregated point cloud) mode.<br></p><p>Usually, if a vehicle is equipped with an IMU or Odometry sensor, then it is possible to get the pose of the ego-vehicle in the world frame of reference.</p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     | `Object` |
| `data.sensor_data.frames.[i].sensors`  | <p>List of all the sensors associated with this particular frame with each having:</p><p></p><p><code>sensor\_id</code> : id of the sensor. This is a foreign key to the sensor id mentioned in the <code>sensor\_meta</code> of the sequence data</p><p></p><p><code>data\_url</code> : A URL to the file containing the data captured from the sensor for this frame. In order to annotate lidar data, please share point clouds in ascii encoded PCD format.<br></p><p><code>sensor\_pose</code> : This key specifies the pose of respective sensors in a common frame of reference. <br><br>If the <code>ego\_pose</code> is available in the world frame of reference, then you should specify the <code>sensor\_pose</code> of individual sensors in the same world frame of reference. In such cases, the pose might change in every frame, as the vehicle moves. <br><br>If the <code>ego\_pose</code> is not available, then all <code>sensor\_pose</code> can be specified with respect to a fixed point on the vehicle. In such cases, the pose will not change between frames.</p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    | `Object` |

Please share point clouds in `ascii` encoded PCD format.

{% hint style="info" %}
If you are sharing the `ego_pose` and `sensor_pose` in the world frame of reference, then the points in the PCD file should also be in the world frame of reference
{% endhint %}

PCD format Specification: <https://pcl.readthedocs.io/projects/tutorials/en/latest/pcd_file_format.html>

```csharp
# .PCD v0.7 - Point Cloud Data file format 
VERSION 0.7
FIELDS x y z
SIZE 4 4 4
TYPE F F F
COUNT 1 1 1
WIDTH 47286
HEIGHT 1
VIEWPOINT 0 0 0 1 0 0 0
POINTS 47286
DATA ascii
5075.773 3756.887 107.923
5076.011 3756.876 107.865
5076.116 3756.826 107.844
5076.860 3756.975 107.648
5077.045 3756.954 107.605
5077.237 3756.937 107.559
5077.441 3756.924 107.511
5077.599 3756.902 107.474
5077.780 3756.885 107.432
5077.955 3756.862 107.391
...
```

## Creating jobs with pre-labeled data

If you have data which has been labeled previously by an ML model or by human labelers, you can create jobs with such labels already created. To do this, you need to send the annotation data in the `data.maker_response` key in the payload. The annotation data needs to be in our annotation format.

Here's an example:

```json
{
  "reference_id": "001",
  "data": {
    "sensor_data": {
      "frames": [...],
      "sensor_meta": [...]
    },
    "maker_response": {
      "sensor_fusion_v2": {
        "data": {
          "frames": [
            {
              "_id": "0030"
            },
            {
              "_id": "0031"
            }
          ],
          "tracks": [
            {
              "_id": "5b88b0cc-3ba9-4197-a6a1-4b99e976025c",
              "color": "rgb(33, 196, 254)",
              "label": "Car"
            },
            {
              "_id": "afe4ebe9-5c2f-43fb-9d61-5c58a1c57d7d",
              "color": "rgb(63, 225, 250)",
              "label": "Bus"
            }
          ],
          "sensors": [
            {
              "sensor_id": "Lidar",
              "sensor_type": "LIDAR"
            },
            {
              "sensor_id": "front_left_camera",
              "sensor_type": "CAMERA"
            }
          ],
          "annotations": [...]
        }
      }
    }
  },
  "work_flow_id": "2aae1234-acac-1234-eeff-12a22a237bbc"
}
```

You can check the structure for various `annotation_object` below:

{% tabs %}
{% tab title="Rectangles" %}

```json
{
  "_id": "b45e76d2-8295-4212-9134-a60640556b09",
  "type": "rectangle",
  "label": "Car",
  "source": "images",
  "frame_id": "0030",
  "track_id": "5b88b0cc-3ba9-4197-a6a1-4b99e976025c",
  "sensor_id": "side_right_camera",
  "attributes": {
    "pose": {
      "value": "standing"
    }
  },
  "coordinates": [
    {
      "x": 0.47711045883773673,
      "y": 0.11618729909271992
    },
    {
      "x": 0.7399349526734161,
      "y": 0.11618729909271992
    },
    {
      "x": 0.7399349526734162,
      "y": 0.5347698204628802
    },
    {
      "x": 0.47711045883773673,
      "y": 0.5347698204628804
    }
  ]
}
```

{% endtab %}

{% tab title="Polygon" %}

```json
{
  "_id": "7d7e3b56-2298-4fa9-abe4-7b123d5fb927",
  "type": "polygon",
  "edges": {
    "e1": [
      "p1",
      "p2"
    ],
    "e2": [
      "p2",
      "p3"
    ],
    "e3": [
      "p3",
      "p4"
    ]
  },
  "label": "Bus",
  "points": {
    "p1": {
      "x": 0.430122,
      "y": 0.437186
    },
    "p2": {
      "x": 0.584285,
      "y": 0.449056
    },
    "p3": {
      "x": 0.532898,
      "y": 0.521459
    },
    "p4": {
      "x": 0.253617,
      "y": 0.522646
    }
  },
  "source": "images",
  "frame_id": "0030",
  "track_id": "afe4ebe9-5c2f-43fb-9d61-5c58a1c57d7d",
  "sensor_id": "rear_left_camera",
  "attributes": {
    "pose": {
      "value": "standing"
    }
  }
}
```

{% endtab %}

{% tab title="2D Line" %}

```json
{
  "_id": "7b9ec35a-f7da-4717-bdd1-2b15e57adfd5",
  "type": "line",
  "edges": {
    "e1": [
      "p1",
      "p2"
    ],
    "e2": [
      "p2",
      "p3"
    ]
  },
  "label": "Lane",
  "points": {
    "p1": {
      "x": 0.430122,
      "y": 0.437186
    },
    "p2": {
      "x": 0.584285,
      "y": 0.449056
    },
    "p3": {
      "x": 0.532898,
      "y": 0.521459
    }
  },
  "source": "images",
  "frame_id": "0032",
  "track_id": "f859fee0-e0a0-4e9c-8c73-e9874ad25c7a",
  "sensor_id": "rear_left_camera",
  "attributes": {
    "pose": {
      "value": "standing"
    }
  }
}
```

{% endtab %}

{% tab title="Cuboid" %}

```json
{
  "_id": "5b88b0cc-3ba9-4197-a6a1-4b99e976025c",
  "type": "cuboid3d",
  "label": "Car",
  "center": {
    "x": 1.0063,
    "y": 18.4305,
    "z": -0.22
  },
  "source": "pointcloud",
  "frame_id": "0030",
  "rotation": {
    "_w": -0.6632011035134499,
    "_x": 0,
    "_y": 0,
    "_z": -0.7484412443863194
  },
  "track_id": "5b88b0cc-3ba9-4197-a6a1-4b99e976025c",
  "sensor_id": "Lidar",
  "attributes": {
    "pose": {
      "value": "standing"
    }
  },
  "dimensions": {
    "width": 1.0763,
    "height": 1.7,
    "length": 1.8247
  }
}
```

{% endtab %}

{% tab title="3D Line" %}

```json
{
  "_id": "f859fee0-e0a0-4e9c-8c73-e9874ad25c7a",
  "type": "line3d",
  "edges": {
    "e1": [
      "p0",
      "p1"
    ],
    "e2": [
      "p1",
      "p2"
    ]
  },
  "label": "Lane",
  "source": "pointcloud",
  "frame_id": "0030",
  "track_id": "f859fee0-e0a0-4e9c-8c73-e9874ad25c7a",
  "sensor_id": "Lidar",
  "attributes": {
    "pose": {
      "value": "standing"
    }
  },
  "coordinates": [
    {
      "x": -3.6292814640886446,
      "y": 19.556498318998976,
      "z": -1.070655124671528
    },
    {
      "x": -4.152039272525941,
      "y": 16.312260187877563,
      "z": -1.070655124671528
    },
    {
      "x": -3.307040128623351,
      "y": 14.59078700815676,
      "z": -1.070655124671528
    }
  ]
}
```

{% endtab %}
{% endtabs %}


# Output format

## JOB RESULT

<mark style="color:blue;">`GET`</mark> `https://api.playment.io/v1/projects/:project_id/jobs/:job_id`

This endpoint allows you to get the annotations created on a job.

#### Path Parameters

| Name        | Type   | Description                                                                              |
| ----------- | ------ | ---------------------------------------------------------------------------------------- |
| job\_id     | string | ID of the job. You would have received this ID in the response when you created the job. |
| project\_id | string | ID of the project where the job was created                                              |

#### Headers

| Name      | Type   | Description                |
| --------- | ------ | -------------------------- |
| x-api-key | string | API key for authentication |

{% tabs %}
{% tab title="200 Job results successfully retrieved." %}

```javascript
{
    "data": {
        "project_id": "905ea3ee-6f62-4bb7-8c31-471e486d9202",
        "reference_id": "001",
        "job_id": "3f3e8675-ca69-46d7-aa34-96f90fcbb732",
        "batch_id": "468b6ae3-e98d-4d08-9427-b6e7a016054c",
        "status": "completed",
        "work_flow_id": "51bb440c-f0ed-4286-8984-ea399cbc1f9w",
        "priority_weight": 5,
        "tag": "2aae1234-acac-1234-eeff-12a22a237bbc",//tag is the workflow_id for the job  
        "result": "https://playment-data-uploads.s3.ap-south-1.amazonaws.com/sample-result.json"
    },
    "success": true
}
```

{% endtab %}
{% endtabs %}

## ATTACHMENT

<mark style="color:blue;">`GET`</mark> `https://api.playment.io/v1/attachments?url=:result_url`

The *result\_url* (`data.result`) returned by the GET Job result API is a private URL (Well, it's public till 15th July 2021, after which we'll enforce it to be private). You need to use this Attachment access API to securely fetch the results. Please refer to the Attachment Access API document for more detail.

#### Path Parameters

| Name        | Type   | Description                                   |
| ----------- | ------ | --------------------------------------------- |
| result\_url | string | Result URL returned by the GET job result API |

#### Headers

| Name      | Type   | Description                |
| --------- | ------ | -------------------------- |
| x-api-key | string | API key for authentication |

{% tabs %}
{% tab title="200 " %}

```
The API will redirect to a signed URL of the attachment
```

{% endtab %}
{% endtabs %}

## Result Object

```javascript
{
  "data": {
    "annotation_data": {
      "annotations": []
    },
    "sensor_data": {
      "frames": [] //This is the same list you sent while creating the job
    }
  }
}
```

The annotations list contains objects, where each object is an *tracker*. A tracker tracks an object across frames. The `frames` key in the tracker object maps each *annotation object* in the tracker to the `frame_id` it belongs to.&#x20;

```javascript
{
  "_id": "e94425cc-0984-4af1-95d5-b73234abcd63",
  "type": "cuboid3d",
  "color": "rgb(185,100,192)",
  "label": "Car",
  "frames" : {
    "frame001" : {<annotation_object>}
  }
}
```

{% tabs %}
{% tab title="3D Bounding Box" %}

```javascript
{
  "_id": "221efcfe-ca02-4845-8582-53d5e969edfe",
  "color": "rgb(185,100,192)",
  "label": "Car",
  "center": {
    "x": -7.9712,
    "y": -1.3861,
    "z": 1.1033
  },
  "keyFrame": true,
  "rotation": {
    "_w": -0.9952638830524981,
    "_x": -0.008698959266850841,
    "_y": -0.0006932023355776871,
    "_z": -0.09681761549149911
  },
  "attributes": {},
  "dimensions": {
    "width": 1.8678,
    "height": 1.9448,
    "length": 4.8818
  }
}
```

{% endtab %}

{% tab title="3D Lines" %}

```json
{
    "_id": "30207bd4-0241-4cf2-b077-4a3db3588753",
    "label": "Single Solid Line",
    "type": "line3d",
    "attributes": {
        "Color": {
            "value": "Yellow"
        }
    },
    "coordinates": [
        {
            "x": 0.525618,
            "y": 0.301574,
            "z": 0.601574
        },
        {
            "x": 0.494912,
            "y": 0.481149,
            "z": 0.201574
        },
        {
            "x": 0.580676,
            "y": 0.482843,
            "z": 0.101574
        }
    ],
    "edges": {
        "e1": [
            "p1",
            "p2"
        ],
        "e2": [
            "p2",
            "p3"
        ]
    },
    "sensor_id": "lidar",
    "frame_id": "frame001",
    "track_id": "2b1e061c-5a30-4ce3-b176-8fb04b058a6e",
    "color": "rgb(254,109,236)"
}
```

{% endtab %}

{% tab title="3D Keypoints" %}

```json
{
    "_id": "30207bd4-0241-4cf2-b077-4a3db3588753",
    "label": "keypoints3d",
    "type": "keypoints3d",
    "attributes": {
        "static": {
            "state": "editable",
            "value": "b1"
        },
        "occlusion": {
            "state": "editable",
            "value": "a1"
        }
    },
    "keypoints": {
        "p1" : {
            "x": 0.525618,
            "y": 0.301574,
            "z": 0.212222,
            "label" : "top"
        },
        "p2" : {
            "x": 0.494912,
            "y": 0.481149,
            "z": 0.212222,
            "label" : "left"
        },
        "p3" : {
            "x": 0.580676,
            "y": 0.482843,
            "z": 0.212222,
            "label" : "right"
        }
    },
    "edges": {
        "e1": [
            "p1",
            "p2"
        ],
        "e2": [
            "p2",
            "p3"
        ],
        "e3": [
            "p3",
            "p1"
        ]
    }
}
```

{% endtab %}
{% endtabs %}


# Point Cloud Segmentation

In this section, We have added some examples to understand how to create an 3D point cloud annotation job and export the results once the job has been labeled.

GT Studio supports multi-sensor setups, i.e. where you have a point cloud along with images from multiple cameras. If you provide calibration information (poses of each sensor and camera intrinsic), the tool will automatically project annotations from the 3D space to the cameras.

{% hint style="warning" %}
We support 3D point cloud segmentation in our enterprise plan as a fully managed service offering. Please [contact us](https://playment.io/sign-up) if you are interested in 3D point cloud segmentation.
{% endhint %}


# Create a job

## A JOB

<mark style="color:green;">`POST`</mark> `https://api.playment.io/v1/projects/:project_id/jobs`

This endpoint allows you to create a job

#### Path Parameters

| Name        | Type   | Description                                           |
| ----------- | ------ | ----------------------------------------------------- |
| project\_id | string | ID of the project in which you want to create the job |

#### Headers

| Name      | Type   | Description                |
| --------- | ------ | -------------------------- |
| x-api-key | string | API key for authentication |

#### Request Body

| Name           | Type   | Description                                                                                                                                                                                                                                                                                                            |
| -------------- | ------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| batch\_id      | string | <p>A batch is a way to organize multiple jobs under one <code>batch\_id</code>.  You can create new batches from the dashboard or by using the batch creation API.<br><br>If <code>batch\_id</code> is left empty or the key is not present, the job is created in the <code>Default batch</code> in your project.</p> |
| work\_flow\_id | string | The ID of the workflow inside which you want to create the job                                                                                                                                                                                                                                                         |
| data           | object | The `data` object contains all the information and attachments required to label a job. The `data` object is defined below                                                                                                                                                                                             |
| reference\_id  | string | The unique identifier of the job                                                                                                                                                                                                                                                                                       |

{% tabs %}
{% tab title="200 " %}

```
{
  "data": {
    "job_id": "3f3e8675-ca69-46d7-aa34-96f90fcbb732",
    "reference_id": "001",
    "work_flow_id": "2aae1234-acac-1234-eeff-12a22a237bbc"
  },
  "success": true
}
```

{% endtab %}
{% endtabs %}

## Payload

```javascript
{
  "reference_id": "001",
  "workflow_id": "2aae1234-acac-1234-eeff-12a22a237bbc",
  "data": {
    "sensor_data": {
      "sensor_meta": [
        {
          "name": "lidar",
          "state": "editable",
          "modality": "lidar",
          "primary_view": true,
          "id": "lidar"
        },
        {
          "intrinsics": {
            "k2": 0,
            "fy": 1300,
            "skew": 0,
            "k1": 0,
            "p2": 0,
            "cy": 600,
            "cx": 900,
            "k4": 0,
            "fx": 1400,
            "k3": 0,
            "scale_factor": 1,
            "p1": 0
          },
          "state": "editable",
          "name": "18158562",
          "modality": "camera",
          "primary_view": false,
          "id": "18158562"
        }
      ],
      "frames": [
        {
          "ego_pose": {
            "position": {
              "z": 0,
              "x": 0,
              "y": 0
            },
            "heading": {
              "z": 0,
              "w": 1,
              "x": 0,
              "y": 0
            }
          },
          "frame_id": "316930954119847",
          "sensors": [
            {
              "sensor_id": "18158562",
              "data_url": "https://xyz.s3.com/123.pcd",
              "sensor_pose": {
                "position": {
                  "z": 1.52,
                  "x": 1.35,
                  "y": 0
                },
                "heading": {
                  "z": 0,
                  "w": 1,
                  "x": 0,
                  "y": 0
                }
              }
            }
          ]
        }
      ]
    }
  },
  "batch_id": "4b656861-052b-452b-9835-5aa11d619642"
}
```

| Key                            | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |   Type   |
| ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :------: |
| `data.sensor_data`             | Contains a sensors list, ego\_pose object and sensor metadata list                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                | `Object` |
| `data.sensor_data.sensor_meta` | <p>Contains a list of all the sensors with each having metadata information like <br><code>id</code> : id of sensor<br><code>name</code> : name of sensor <br><code>modality</code> : lidar / camera</p><p><br>If the sensor is a camera, you can add the camera <code>intrinsic</code> values as well as the <code>camera\_model</code>. These values are used along with the sensor\_pose to create projections between sensors.</p><p></p><p><code>camera\_model</code>:  one of <code>brown\_conrady</code> , <code>fisheye</code>  or <code>cylindricalV2</code> (for cylindrical camera model).</p><p>If this key doesn't exist or is null, the tool will assume <code>brown\_conrady</code>.</p><p></p><p>The <code>intrinsics</code> object contains the following keys:</p><p><code>cx</code>: principal point x value<br><code>cy</code>: principal point y value<br><code>fx</code>: focal length in x-axis<br><code>fy</code>: focal length in y-axis<br><code>k1, k2, k3, k4, k5, k6</code>: Radial distortion coefficients<br><code>p1, p2</code>: Tangential distortion coefficients<br><code>skew</code>: camera skew coefficient<br><code>scale\_factor</code>: The factor by which the image has been downscaled (For example, scale\_factor will be 2 if the original image is twice as large as the downscaled image)</p><p></p><p>If the <code>camera\_model</code> is <code>brown\_conrady</code> then the distortion coefficients should be one of the following combinations:</p><ul><li>k1, k2, p1, p2</li><li>k1, k2, p1, p2, k3</li><li>k1, k2, p1, p2, k3, k4, k5, k6</li></ul><p></p><p>If the <code>camera\_model</code> is <code>fisheye</code> then the distortion coefficients should be the following combination:</p><ul><li>k1, k2, k3, k4</li></ul><p></p><p>If the <code>camera\_model</code> is <code>cylindricalV2</code> (for cylindrical camera model) then no distortion coefficients (k1 - k6, p1, p2) are needed or used.</p><p></p><p>The remaining coefficients can be ignored or be assigned a value of 0</p><p></p><p>OpenCV reference<a href="https://docs.opencv.org/2.4/modules/calib3d/doc/camera_calibration_and_3d_reconstruction.html">: Camera calibration and 3D reconstruction</a></p> |  `List`  |
| `data.sensor_data.ego_pose`    | <p>Contains the pose of a fixed point on the ego vehicle in the world frame of reference in the form of position (in (x, y, z)) and orientation (as quaternion (w, x, y, z))</p><p></p><p>In case the pose of the ego vehicle is available in the world frame of reference, The tool can allow annotators to mark objects as stationary and toggle APC (Aggregated point cloud) mode.<br></p><p>Usually, if a vehicle is equipped with an IMU or Odometry sensor, then it is possible to get the pose of the ego-vehicle in the world frame of reference.</p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     | `Object` |
| `data.sensor_data.sensors`     | <p>List of all the sensors associated with this particular frame with each having:</p><p></p><p><code>sensor\_id</code> : id of the sensor. This is a foreign key to the sensor id mentioned in the <code>sensor\_meta</code> of the sequence data</p><p></p><p><code>data\_url</code> : A URL to the file containing the data captured from the sensor for this frame. In order to annotate lidar data, please share point clouds in ascii encoded PCD format.<br></p><p><code>sensor\_pose</code> : This key specifies the pose of respective sensors in a common frame of reference. <br><br>If the <code>ego\_pose</code> is available in the world frame of reference, then you should specify the <code>sensor\_pose</code> of individual sensors in the same world frame of reference. In such cases, the pose might change in every frame, as the vehicle moves. <br><br>If the <code>ego\_pose</code> is not available, then all <code>sensor\_pose</code> can be specified with respect to a fixed point on the vehicle. In such cases, the pose will not change between frames.</p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |  `List`  |

Please share point clouds in `ascii` encoded PCD format

PCD format Specification: <https://pcl.readthedocs.io/projects/tutorials/en/latest/pcd_file_format.html>

```c
# .PCD v0.7 - Point Cloud Data file format 
VERSION 0.7
FIELDS x y z
SIZE 4 4 4
TYPE F F F
COUNT 1 1 1
WIDTH 47286
HEIGHT 1
VIEWPOINT 0 0 0 1 0 0 0
POINTS 47286
DATA ascii
5075.773 3756.887 107.923
5076.011 3756.876 107.865
5076.116 3756.826 107.844
5076.860 3756.975 107.648
5077.045 3756.954 107.605
5077.237 3756.937 107.559
5077.441 3756.924 107.511
5077.599 3756.902 107.474
5077.780 3756.885 107.432
5077.955 3756.862 107.391
...
```

### Visualizing intensity/reflectivity information

You can send additional data like **Intensity or reflectivity values** for each point in the PCD file. This can help annotators segment reflective surfaces like lane markings.

You can refer to a sample PCD structure below.

```c
# .PCD v0.7 - Point Cloud Data file format
VERSION 0.7
FIELDS x y z intensity
SIZE 4 4 4 4
TYPE F F F F
COUNT 1 1 1 1
WIDTH 33345
HEIGHT 1
VIEWPOINT 0 0 0 1 0 0 0
POINTS 33345
DATA ascii
6.381713394829211 20.46125301261318 -2.413081058852035 0.02745098
5.28544895349773 16.913142630625543 -2.283128795562235 0.023529412
4.50899949078274 14.40011307442226 -2.1906859549297164 0.023529412
3.90763970412707 12.453374568477361 -2.108260110209615 0.023529412
2.9475040373348147 11.063306463789342 -2.0292308745898255 0.03137255
2.648762017271138 9.92654497521169 -1.991709336214386 0.03529412
3.4192604688595 9.368384486158 -1.99749275125155 0.03137255
...
```

Once you share the data with the above format, annotators can utilize it to view point-cloud colors based on the intesity. It'll look like this:&#x20;

![](https://1898243238-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MAyflu2a3TSnjJox7Sw%2F-Mb_aWz4XA9IfnCMR0CS%2F-Mb_arDAyWg-zJVEg_-J%2Fezgif.com-gif-maker.gif?alt=media\&token=5766fd7b-3b55-490f-a0d8-cecb6cc00a11)

### Helper Python script to create jobs

```python
import json
import requests
from copy import deepcopy

## Functions
def create_batch(BATCH_NAME):
    base_url = f"https://api.playment.io/v1/projects/{PROJECT_ID}/batch"
    DATA = {"name":BATCH_NAME}
    response = requests.post(base_url, headers={'x-api-key': CLIENT_KEY}, json=DATA)
    response_data = response.json()
    if response.status_code >= 500:
        raise Exception(f"Something went wrong at Playment's end {response.status_code}")
    if 400 <= response.status_code < 500:
        raise Exception(f"{response_data['error']['message']} {response.status_code}")
    print(response_data)
    return response_data

def Upload_jobs(DATA):
    base_url = f"https://api.playment.io/v1/projects/{PROJECT_ID}/jobs"
    response = requests.post(base_url, headers={'x-api-key': CLIENT_KEY}, json=DATA)
    response_data = response.json()
    if response.status_code >= 500:
        raise Exception(f"Something went wrong at Playment's end {response.status_code}")
    if 400 <= response.status_code < 500:
        raise Exception(f"{response_data['error']['message']} {response.status_code}")
    print(response_data)
    return response_data

## Set project details

# Details for creating JOBS,
# PROJECT_ID ->> ID of project in which job needed to be created
# CLIENT_KEY ->> secret client key to create JOBS
# WORK_FLOW_ID ->> You can ask this from TELUS International side
# BATCH_ID ->> The batch in which JOB needed to be created

PROJECT_ID = ''
CLIENT_KEY = ''
WORK_FLOW_ID = ''
BATCH_ID = ''


## Job creation payload structure

payload_data_structure ={
    "reference_id": "",                 # reference_id is the unique reference id for the job
    "data": {
        "sensor_data": {
            "sensors": [],
            "ego_pose": {               # ego_pose is the ego vehicle's pose
                "position": {           # ego vehicle's position
                    "x": 0,
                    "y": 0,
                    "z": 0
                },
                "heading": {            # ego vehicle's heading in quaternion format
                    "w": 1,
                    "x": 0,
                    "y": 0,
                    "z": 0
                }
            },
            "sensor_meta": []           # sensor_meta contains meta data for lidar and camera sensors
        }
    },
    "work_flow_id": "",                 # this is the id of the workflow in which the jobs are to be created
    "batch_id": ""                     # this is the batch_id of the batch in which jobs are to be created

}

sensor_data_structure = {
  "sensor_id": "",                      # This is the sensor's id
  "data_url": "",                       # sensor's data's URL
  "sensor_pose": {                      # This are the sensor's extrinsic values
    "position": {                       # sensor's position
      "x": 0,
      "y": 0,
      "z": 0
    },
    "heading": {                        # sensor's heading in quaternion format
      "w": 1,
      "x": 0,
      "y": 0,
      "z": 0
    }
  }
}

lidar_sensor_meta_structure = {         # lidar sensor's metadata. There can only be one lidar sesnor
  "id": "",                             # lidar sensor's ID
  "name": "",                           # should be kept same as lidar sensor's ID
  "state": "editable",                  # should be kept as editable only
  "modality": "lidar",                  # moality specifies the type of sensor [lidar/camera]
  "primary_view": True                  # should be kept True for lidar sensor
}

camera_sensor_meta_structure = {        # camer sensor's metadata. There can be multiple camera sensors
  "id": "",                             # camera sensor's ID
  "name": "",                           # should be kept same as camera sensor's ID
  "state": "editable",                  # should be kept as editable only           
  "modality": "camera",                 # moality specifies the type of sensor [lidar/camera]
  "camera_model": "brown_conrady",      # specifies the model of camera
  "primary_view": False,                # should be kept as False for all camera sensors
  "intrinsics": {                       # camera sensor's intrinsic values
    "cx": 0,
    "cy": 0,
    "fx": 0,
    "fy": 0,
    "k1": 0,
    "k2": 0,
    "k3": 0,
    "k4": 0,
    "p1": 0,
    "p2": 0,
    "skew": 0,
    "scale_factor": 1
  }
}

if __name__ == "__main__":
    
    ## Set sensor id and data url (Only 1 lidar can be present per job)

    # Here lidar's sensor_id is the key and pcd file for each job is in the list
    lidar_data = [
            "https://example.com/pcd_url_1",
            "https://example.com/pcd_url_2"
        ]
    

    ## Set camera sensor ids and data urls (1 or more cameras can be present per job)

    # Here camera's sensor_id is the key and image url for each job is in the list corresponding to that camera
    camera_data = {
        'camera_1': [
            "https://example.com/image_url_1",
            "https://example.com/image_url_2"        ],
        "camera_2": [
            "https://example.com/image_url_3",
            "https://example.com/image_url_4"
        ]
    }



    lidar_sensor_id = 'lidar'  # set your lidar sensor id


    # validate the number of urls are equal for each sensor
    for camera_sensor_id, camer_sensor_urls in camera_data.items():
        assert len(camer_sensor_urls) == len(lidar_data), f"Number of URLs are not equal for {camera_sensor_id}"

    # get number of jobs
    numer_of_jobs = len(lidar_data)


    # create the jobs
    for i in range(numer_of_jobs):
       
        # define the payload for job creation
        payload_data = deepcopy(payload_data_structure)
        payload_data['reference_id'] = lidar_data[i].replace('.pcd', '') # you can set unique reference id as per your wish
        payload_data['work_flow_id'] = WORK_FLOW_ID
        payload_data['batch_id'] = BATCH_ID

        # define lidar sensor meta and add it to payload data
        lidar_sensor_meta = deepcopy(lidar_sensor_meta_structure)
        lidar_sensor_meta['id'] = lidar_sensor_id
        lidar_sensor_meta['name'] = lidar_sensor_id
        payload_data['data']['sensor_data']['sensor_meta'].append(lidar_sensor_meta)

        # define lidar sensor data and add it to payload data
        lidar_sensor_data = deepcopy(sensor_data_structure)
        lidar_sensor_data['sensor_id'] = lidar_sensor_id
        lidar_sensor_data['data_url'] = lidar_data[i]
        # set appropriate lidar position and heading, corrently defaulted it to (0,0,0),(1,0,0,0) 
        lidar_sensor_data['sensor_pose']['position']['x'] = 0
        lidar_sensor_data['sensor_pose']['position']['y'] = 0
        lidar_sensor_data['sensor_pose']['position']['z'] = 0
        
        lidar_sensor_data['sensor_pose']['heading']['w'] = 1
        lidar_sensor_data['sensor_pose']['heading']['x'] = 0
        lidar_sensor_data['sensor_pose']['heading']['y'] = 0
        lidar_sensor_data['sensor_pose']['heading']['z'] = 0
        payload_data['data']['sensor_data']['sensors'].append(lidar_sensor_data)

        for camera_sensor_id, camera_sensor_urls in camera_data.items():
            # define camera sensor meta and add it to payload
            camera_sensor_meta = deepcopy(camera_sensor_meta_structure)
            camera_sensor_meta['id'] = camera_sensor_id
            camera_sensor_meta['name'] = camera_sensor_id
            payload_data['data']['sensor_data']['sensor_meta'].append(camera_sensor_meta)

            # define camera sensor data and add it to payload data
            camera_sensor_data = deepcopy(sensor_data_structure)
            camera_sensor_data['sensor_id'] = camera_sensor_id
            camera_sensor_data['data_url'] = camera_sensor_urls[i]
            # set appropriate camera position and heading, corrently defaulted it to (0,0,0),(1,0,0,0) 
            camera_sensor_data['sensor_pose']['position']['x'] = 0
            camera_sensor_data['sensor_pose']['position']['y'] = 0
            camera_sensor_data['sensor_pose']['position']['z'] = 0

            camera_sensor_data['sensor_pose']['heading']['w'] = 1
            camera_sensor_data['sensor_pose']['heading']['x'] = 0
            camera_sensor_data['sensor_pose']['heading']['y'] = 0
            camera_sensor_data['sensor_pose']['heading']['z'] = 0
            
            payload_data['data']['sensor_data']['sensors'].append(camera_sensor_data)

        #print(json.dumps(payload_data))
        Upload_jobs(payload_data)
```


# Get job results

## JOB RESULT

<mark style="color:blue;">`GET`</mark> `https://api.playment.io/v1/projects/:project_id/jobs/:job_id`

This endpoint allows you to get the annotations created on a job.

#### Path Parameters

| Name        | Type   | Description                                                                              |
| ----------- | ------ | ---------------------------------------------------------------------------------------- |
| job\_id     | string | ID of the job. You would have received this ID in the response when you created the job. |
| project\_id | string | ID of the project where the job was created                                              |

#### Headers

| Name      | Type   | Description                |
| --------- | ------ | -------------------------- |
| x-api-key | string | API key for authentication |

{% tabs %}
{% tab title="200 Job results successfully retrieved." %}

```javascript
{
    "data": {
        "project_id": "905ea3ee-6f62-4bb7-8c31-471e486d9202",
        "reference_id": "001",
        "job_id": "3f3e8675-ca69-46d7-aa34-96f90fcbb732",
        "batch_id": "468b6ae3-e98d-4d08-9427-b6e7a016054c",
        "status": "completed",
        "work_flow_id": "51bb440c-f0ed-4286-8984-ea399cbc1f9w",
        "priority_weight": 5,
        "tag": "2aae1234-acac-1234-eeff-12a22a237bbc", //tag is the workflow_id for the job  
        "result": "https://playment-data-uploads.s3.ap-south-1.amazonaws.com/sample-result.json"
    },
    "success": true
}
```

{% endtab %}
{% endtabs %}

## ATTACHMENT

<mark style="color:blue;">`GET`</mark> `https://api.playment.io/v1/attachments?url=:result_url`

The *result\_url* (`data.result`) returned by the GET Job result API is a private URL (Well, it's public till 15th July 2021, after which we'll enforce it to be private). You need to use this Attachment access API to securely fetch the results. Please refer to the Attachment Access API document for more detail.&#x20;

#### Path Parameters

| Name        | Type   | Description                                   |
| ----------- | ------ | --------------------------------------------- |
| result\_url | string | Result URL returned by the GET job result API |

#### Headers

| Name      | Type   | Description                |
| --------- | ------ | -------------------------- |
| x-api-key | string | API key for authentication |

{% tabs %}
{% tab title="200 " %}

```
The API will redirect to a signed URL of the attachment
```

{% endtab %}
{% endtabs %}

## Result Object

{% tabs %}
{% tab title="Point Cloud Segmentation" %}

```javascript
{
  "annotation_data": {
    "annotations": [
      {
        "_id": "14e4bd90-6bdc-4571-87e1-adf41908b0ed",
        "_isStationary": false,
        "attributes": {},
        "class_id": "24aaea97-002d-41f1-9632-ce36b829445a",
        "color": "rgb(71, 153, 193)",
        "frame_id": "0",
        "grouping_config": null,
        "label": "Vehicle",
        "label_key": 1,
        "sensor_id": "",
        "text": "Vehicle",
        "track_id": "bce3dd47-0938-4fd7-963b-47e459fda54e",
        "type": "segmentation3d"
      }
    ],
    "frames": [
      {
        "_id": "0"
      }
    ],
    "groups": null,
    "masks": [
      {
        "_id": "8feec956-0d5c-4d3c-b8be-b03d1c8f23a9",
        "frame_id": "0",
        "label_url": "https://xyz.s3.com/123.txt",
        "sensor_id": "18158562",
        "type": "segmentation3d",
        "url": ""
      }
    ],
    "sensors": [
      {
        "sensor_id": "18158562",
        "sensor_type": "CAMERA"
      }
    ],
    "tracks": [
      {
        "_id": "bce3dd47-0938-4fd7-963b-47e459fda54e",
        "attributes": null,
        "color": "rgb(71, 153, 193)",
        "grouping_config": null,
        "label": "",
        "label_id": null,
        "state": "",
        "type": ""
      }
    ]
  },
  "sensor_data": {
    "frames": [
      {
        "ego_pose": {
          "heading": {
            "w": 0.979,
            "x": 0,
            "y": -0.02,
            "z": 0.202
          },
          "position": {
            "x": -40,
            "y": -8,
            "z": -1
          }
        },
        "frame_id": "0",
        "sensors": [
          {
            "data_url": "https://xyz.s3.com/123",
            "original_url": "https://xyz.s3.com/123.jpg",
            "sensor_id": "front_center_rgb",
            "sensor_pose": {
              "heading": {
                "w": 0.98,
                "x": 0,
                "y": -0.05,
                "z": 0.189
              },
              "position": {
                "x": -40,
                "y": -8,
                "z": -1
              }
            }
          }
        ]
      }
    ],
    "sensor_meta": [
      {
        "camera_model": "brown_conrady",
        "id": "18158562",
        "intrinsics": {
          "cx": 950,
          "cy": 500,
          "fx": 1000,
          "fy": 1050,
          "k1": 0.31,
          "k2": -0.024,
          "k3": 0.0017,
          "k4": 0,
          "p1": -0.000466,
          "p2": 0.0002909,
          "scale_factor": 0,
          "skew": 0
        },
        "modality": "camera",
        "name": "front_center_rgb",
        "primary_view": false,
        "state": "editable"
      },
      {
        "id": "18158562",
        "modality": "lidar",
        "name": "front_lidar",
        "primary_view": true,
        "state": "editable"
      }
    ]
  }
}
```

{% endtab %}
{% endtabs %}

To access the PCD mask (`url` in the result object), follow these steps :

1. From the "Frames" object, get the "frame\_id".
2. Go to "Masks" object, and locate the "frame\_id" property with the value needed (from step 1).
3. The "frame\_id" property in "Masks" object will have a "label\_url" attribute.
4. Use the GET Attachment API with the url obtained from "label\_url" attribute.
5. This will generate a Mask file, similar to the sample below.

{% tabs %}
{% tab title="Sample Mask File" %}

```c
[16, 58, 58, 58, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 1, 58, 1, 1,
58, 1, 1, 58, 1, 1, 58, 1, 1, 58, 1, 1, 58, 1, 1, 1, 58, 1, 1, 1, 11, 1, 1, 1,
11, 1, 1, 1, 11, 1, 1, 1, 11, 1, 1, 1, 11, 1, 1, 1, 11, 1, 1, 1, 11, 1, 1, 1,
11, 1, 1, 1, 11, 1, 1, 1, 11, 1, 1, 1, 11, 1, 1, 1, 11, 1, 1, 1, 11, 1, 1, 1,
11, 1, 1, 1, 11, 1, 1, 1, 11, 1, 1, 1, 11, 1, 1, 1, 11, 1, 1, 1, 11, 1, 1, 11,
1, 1, 11, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 1, 4, 1, 4, 4, 1, 4, 1, 4, 4, 1, 4, 4, 1, 4, 1, 4,
1, 4, 4, 4, 1, 4, 4, 4, 1, 4, 1, 4, 1, 4, 1, 1, 4, 1, 1, 1, 1, 4, 1, 1, 1, 1, 4,
1, 1, 1, 1, 4, 1, 4, 1, 4, 1, 4, 1, 1, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 4, 1, 4, 4,
1, 4, 1, 4, 4, 1]
```

{% endtab %}
{% endtabs %}

In the annotation list, each class is associated with a distinct label key, which corresponds to a mask within the array. This label key is aligned with the points in the Point Cloud Data, ensuring that the label key is ordered at the same index as the corresponding point in the Point Cloud Data.


# AWS S3

If you use AWS S3 to store data you can send attachments as `https:` or `http:` URLs. You can also send attachments as `s3:` [protocol URIs](https://docs.aws.amazon.com/cli/latest/reference/s3/) which look like `s3://bucket/key`.

To access private s3 objects, We use **Cross-account Access**.

## **Cross-account Access**

We will fetch attachments from your S3 bucket, using AWS account ID `475757276268` (canonical ID `d4b5723a54db6f9da8a68f4c24233880793bf1d68dd11e7e2b4989bd2c71c59a`). You will need to grant access to TELUS International using [bucket policies](https://docs.aws.amazon.com/AmazonS3/latest/dev/example-bucket-policies.html) or on set permissions on objects [using ACLs](https://docs.aws.amazon.com/AmazonS3/latest/user-guide/set-object-permissions.html).&#x20;

We suggest setting a **Bucket Policy** that shares the bucket's contents with the account of TELUS International.

Here's a sample bucket policy:

```
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Principal": {
                "AWS": [
                    "arn:aws:iam::475757276268:root"
                ]
            },
            "Action": "s3:ListBucket",
            "Resource": "arn:aws:s3:::YOUR_BUCKET_NAME"
        },
        {
            "Sid": "VisualEditor1",
            "Effect": "Allow",
            "Principal": {
                "AWS": [
                    "arn:aws:iam::475757276268:root"
                ]
            },
            "Action": [
                "s3:PutObject",
                "s3:GetObject",
                "s3:DeleteObject"
            ],
            "Resource": [
                "arn:aws:s3:::YOUR_BUCKET_NAME",
                "arn:aws:s3:::YOUR_BUCKET_NAME/*"
            ]
        }
    ]
}
```

Replace `YOUR_BUCKET_NAME` with the name of your bucket, leaving the `/*` as shown or replacing it with a more specific bucket path to further restrict access.

If you are using ACLs (Access Control Lists), you need to update the ACL individually for each object to grant read access to our account, as Bucket ACLs can't grant read permissions to nested objects.

## Granting access to an S3 bucket encrypted with KMS Key

If your S3 bucket uses Customer managed KMS keys for encryption(SSE-KMS), there's an additional step to grant TELUS International the necessary permissions:

1. **IAM Policy on KMS Key:** In addition to the bucket policy or ACLs, you need to modify the policy attached to the Customer KMS key used for encryption. This policy needs to allow  IAM user of TELUS International to perform the following actions:
   1. **kms:GenerateDataKey:** This grants TELUS International permission to generate data keys for encrypting/decrypting objects within your bucket.
   2. **kms:Decrypt:** This allows TELUS International to decrypt objects retrieved from your S3 bucket.

**Steps to update the KMS key policy:**

1. Navigate to the AWS KMS console and select the KMS key used for your S3 bucket encryption.
2. Go to the "Key policy" section.
3. Edit the existing policy or create a new one.
4. Add the following :

```
{
    "Version": "2012-10-17",
    "Id": "kms-policy",
    "Statement": [
        {
            "Sid": "Allow use of the key",
            "Effect": "Allow",
            "Principal": {
                "AWS": [
                    "arn:aws:iam::475757276268:root"
                ]
            },
            "Action": [
                "kms:Encrypt",
                "kms:Decrypt",
                "kms:ReEncrypt*",
                "kms:GenerateDataKey*",
                "kms:DescribeKey"
            ],
            "Resource": "*"
        },
    ]
}
```


# Google Cloud Storage

If you use Google Cloud Storage (GCS) to store data, you can send attachments as `https:` or `http:` URLs. You can also send attachments as `gs:` [protocol URIs](https://cloud.google.com/storage/docs/gsutil) which look like `gs://bucket/key`.

To access private GCS objects, We use **Cross-Project Access**.

## **Cross-project Access**

We will fetch attachments from your GCS bucket, using our GCP service account `ti-it-sa-gtstudio@ti-ai-computervision-prod.iam.gserviceaccount.com`. You will need to grant access to TELUS International on a per-bucket basis using [Cloud IAM permissions](https://cloud.google.com/storage/docs/access-control/using-iam-permissions) or set permissions on objects [using ACLs](https://cloud.google.com/storage/docs/access-control/create-manage-lists).

#### An example on how to provide access to a particular folder inside the bucket using ACLs

Install and set up gsutil - <https://cloud.google.com/storage/docs/gsutil_install> and run the below command

```
gsutil acl ch -r \
  -u ti-it-sa-gtstudio@ti-ai-computervision-prod.iam.gserviceaccount.com:O \
  gs://example-bucket/folder/ 
```

For more info on how to control access to the buckets and objects in GCS using ACLs, please refer this [doc](https://cloud.google.com/storage/docs/gsutil/commands/acl).&#x20;


# Azure Blob Storage

If you use Azure Blob to store your data, we will fetch your data with the help of [shared access signatures](https://docs.microsoft.com/en-us/azure/storage/common/storage-sas-overview) (SAS).

While generating the SAS, we would recommend the clients to set the supported protocol to https and the allowed IP address range to `52.66.129.133/32`


# IP Whitelisting

For customers who don't use AWS or GCP, TELUS International uses a set of IPs for accessing attachments. You can restrict public access to your attachments and whitelist the following IPs:&#x20;

```
13.127.210.121
52.66.129.133
```

##


# Hybrid Cloud

If you don't want TELUS International to access your data and only want to restrict access to your own annotators and team members, you can opt for the hybrid cloud approach.

In our usual approach, you host your raw data (images, point-clouds) in an s3 bucket and share it with TELUS International. TELUS International then copies the data over to its own bucket and serves it to annotators via signed URLs.

In the hybrid approach, you host your raw data in your AWS/GCP/Azure file storage or even your local file storage and don't share access with TELUS International. You then share just the URLs while creating jobs in TELUS International. You have to ensure that your annotators have access to objects in your file storage. This can be done by whitelisting the annotators' IP range if using AWS s3, GCS or Azure Blob storage or by adding your annotators in your local network.

You can also create a signed URL with an expiry date and send that signed URL as part of the job creation POST request.

To enable Hybrid cloud, you will have to make sure attachment validation is off in the workflow. You can go to the workflow settings and disable attachment validation.&#x20;

<figure><img src="https://1898243238-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MAyflu2a3TSnjJox7Sw%2Fuploads%2FSW1wUYt3gXCkdwPPL59E%2Fimage1.gif?alt=media&amp;token=57441e0e-16aa-4bee-8e33-234dd7081e4b" alt=""><figcaption></figcaption></figure>

Apart from raw data, there is another type of data, i.e. labels. These are stored either in  database or s3 of TELUS International (eg. pixel-wise segmentation masks). In the hybrid approach, TELUS International will only store the labels, and not the raw data. Once a job is completed, You will be able to GET the labels via API and store it back in your file storage or database.

<figure><img src="https://1898243238-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MAyflu2a3TSnjJox7Sw%2Fuploads%2FeBcylDSeqWBo7ZxUfujr%2FScreenshot%202024-06-04%20at%205.09.09%E2%80%AFPM.png?alt=media&amp;token=41847f5e-613d-4772-af69-16ed18a3deb6" alt=""><figcaption></figcaption></figure>


# Creating jobs with pre-labeled data

If you have data which has been labeled previously by an ML model or by human labelers, you can create jobs with such labels already created. To do this, you need to send the annotation data in the `data.maker_response` key in the payload. The annotation data needs to be in our annotation format.

You can follow these examples to get started:

1. [Image Annotation](https://playment.gitbook.io/api-reference/image-annotation/create-a-job#creating-jobs-with-pre-labeled-data)
2. [Image Segmentation](https://playment.gitbook.io/api-reference/image-segmentation/create-a-job#creating-jobs-with-pre-labeled-data)
3. [Video Annotation](https://playment.gitbook.io/api-reference/video-annotation/create-a-job#creating-jobs-with-pre-labeled-data)
4. [3D Point Cloud Annotation](/3d-point-cloud-annotation/create-a-job#creating-jobs-with-pre-labeled-data)


# Error Codes

All successful responses are returned with HTTP Status code 200. In case of failure, TELUS International API returns a JSON error response with the parameters that detail the reason for the failure with HTTP status code 400.

| Error Code               | Reason                                                                                                                                                   |
| ------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
| auth-failure             | Unauthorized request. The authentication key provided is incorrect                                                                                       |
| unauthorized             | Unauthorized request. You do not have access to the requested resource. Please make sure that you have access to the project you are trying to access.se |
| FS\_0001                 | Reference ID for the job is already in use. Make sure the reference\_id is unique for each job.                                                          |
| FS\_0002                 | reference\_id is missing. Make sure to provide a unique reference\_id for a job                                                                          |
| FS\_0003                 | Job data provided is not valid. Please check the JSON structure.                                                                                         |
| FS\_0004                 | The job data is empty. Make sure you provide the data for job creation as defined [here](/basic-operations/create-a-job)                                 |
| FS\_0005                 | work\_flow\_id was not provided. Make sure to provide the work\_fow\_id for creating jobs                                                                |
| FS\_0007                 | Attachment could not be accessed or copied                                                                                                               |
| FS\_00011                | Type of the job is invalid. Make sure the type of the job is either TEST or NON\_TEST                                                                    |
| FS\_00012                | Job priority weight is invalid. Make sure the priority weight is in the range of 1-9                                                                     |
| GE\_0001                 | One or more parameter in the payload is invalid. For example, batch\_id is not a UUID                                                                    |
| FS\_0000                 | Something went wrong on our end. Please try again after some time.                                                                                       |
| FS\_0008                 | Something went wrong on our end. Please try again after some time.                                                                                       |
| api\_error               | Something went wrong on our end. Please try again after some time.                                                                                       |
| core.webutil.auther      | Unauthorized request. You do not have access to the requested resource. Please make sure that you have access to the project you are trying to access.   |
| core.webutil.token\_auth | Unauthorized request. The authentication key provided is incorrect                                                                                       |
| BATCH\_CREATION          | A batch with this name already exists. Make sure to provide a unique batch name for a batch.                                                             |
| invalid\_request\_error  | Invalid pageToken provided, please provide the correct page\_token to access the results                                                                 |
| resource\_error          | The resource ID provided is incorrect. Check that your requests are specifying a correct project ID, batch ID, or Job ID.                                |


