NAV
shell python javascript
Contact us

for a Developer API Key

Introduction

Welcome to the SAIA MTM API Documentation! You can use Person API - to get measurements for a person.

Authentication

To authorize, use this code:

import requests

session = requests.Session()
session.headers.update({
    'Authorization': "APIKey 9944b09199c62bcf9418ad846dd0e4bbdfc6ee4b"
    })
session.get('https://saia.3dlook.me/api/v2/persons/')
# With shell, you can just pass the correct header with each request
curl "https://saia.3dlook.me/api/v2/persons/"
  -H "Authorization: APIKey 9944b09199c62bcf9418ad846dd0e4bbdfc6ee4b"
var settings = {
    "async": true,
    "crossDomain": true,
    "url": "https://saia.3dlook.me/api/v2/persons/",
    "method": "GET",
    "headers": {
        "Authorization": "APIKey 9944b09199c62bcf9418ad846dd0e4bbdfc6ee4b",
        },
    "processData": false,
}
$.ajax(settings).done(function (response) {
});

Make sure to replace 9944b09199c62bcf9418ad846dd0e4bbdfc6ee4b with your API key.

SAIA uses API keys to allow access to the API. Please check your API key in your Mobile Tailor admin panel.

For client authentication, include the token key in all API requests to the server in a header. The key should be prefixed by the string literal ""APIKey,"" with a whitespace separating the two strings. For example:

Authorization: APIKey 9944b09199c62bcf9418ad846dd0e4bbdfc6ee4b

Correct Flow

To start body calculation parameters, you need to create a Person object. Complete Person with all required data for calculations, you can build it in TWO WAYS. It depends on your options to send base64 encoded photos:

Single Request

If it's ok for you to decode photos to Base64 format, you can:

Two Requests

If you want to send photos as files:

Correctly GET results

Incorrect Photo

If you got an error on the calculation task of side or front photo, you can:

Soft Validation Parameters

Parameter Validation Description
legs_distance > 28 Distance between legs, in cm
body_area_percentage = 0.7 Percentage of body on the photo

Person Model

Create a New Person

import requests

headers = {
    'Authorization': 'APIKey <YOUR_API_KEY_HERE>',
    'Content-Type': 'application/json'
}

payload = {
    'gender': 'female',
    'height': 170,
    'weight': 70.0
}

response = requests.request('POST', 'https://saia.3dlook.me/api/v2/persons/?measurements_type=all', data=payload, headers=headers)
print(response.text)
curl "https://saia.3dlook.me/api/v2/persons/?measurements_type=all"
  -X POST
  -H "Authorization: APIKey <YOUR_API_KEY_HERE>"
  -d '{
    "gender": "female",
    "height": 170,
    "weight": 70.0
}'
var payload = {
    "gender": "female",
    "height": 170,
    "weight": 70.0
}

var settings = {
    "async": true,
    "crossDomain": true,
    "url": "https://saia.3dlook.me/api/v2/persons/?measurements_type=all",
    "method": "POST",
    "headers": {
    "Content-Type": "application/json",
        "Authorization": "APIKey <YOUR_API_KEY_HERE>",
        },
    "processData": false,
    "data": JSON.stringify(payload)
}

$.ajax(settings).done(function (response) {
console.log(response);
});

The above command returns JSON structured like this:

{
    "id": 3,
    "url": "https://saia.3dlook.me/api/v2/persons/3/?measurements_type=all",
    "gender": "female",
    "height": 170,
    "weight": 70.0
}

This endpoint creates a new person, with metadata first and then the partial update with front and side images, with all parameters with front image and side image Base64 encoded.

HTTP Request

POST https://saia.3dlook.me/api/v2/persons/?measurements_type=all

Request Body

The request body should be an "application/json" encoded object, containing the following items.

Parameter Type Validation Description
gender string required, male or female gender of person, male or female
height integer required, >= 150, <= 220 height of person, in cm
weight float required, >= 30, <= 200 weight of person, in kg

Update a Specific Person

import requests

headers = {
    'Authorization': 'APIKey <YOUR_API_KEY_HERE>',
    'Content-Type': 'application/json'
}

files={
    'front_image': open('path_to_file', 'rb'),
    'side_image': open('path_to_file', 'rb'),
}
response = requests.request('PUT', 'https://saia.3dlook.me/api/v2/persons/3/?measurements_type=all', files=files, headers=headers)
print(response.text)
curl "https://saia.3dlook.me/api/v2/persons/3/?measurements_type=all"
  -X PUT
  -H "Authorization: APIKey <YOUR_API_KEY_HERE>"
  -F front_image=@/path/to/files/front_photo.jpg \
  -F side_image=@/path/to/files/side_photo.jpg
var form = new FormData();
form.append("front_image", $('your-input[type=file]')[0].files[0]);
form.append("side_image", $('your-input[type=file]')[0].files[0]);

var settings = {
    "async": true,
    "crossDomain": true,
    "url": "https://saia.3dlook.me/api/v2/persons/3/?measurements_type=all",
    "method": "PUT",
    "headers": {
        "Authorization": "APIKey <YOUR_API_KEY_HERE>",
        },
    "processData": false,
    "contentType": false,
    "mimeType": "multipart/form-data",
    "data": form
}

$.ajax(settings).done(function (response) {
console.log(response);
});

The above command returns JSON structured like this:

{
    "task_set_url": "https://saia.3dlook.me/api/v2/queue/4d563d3f-38ae-4b51-8eab-2b78483b153e/"
}

Response also contains header:

"Location": "https://saia.3dlook.me/api/v2/queue/4d563d3f-38ae-4b51-8eab-2b78483b153e/"

This endpoint uploads front and side images to a new person, if you are not able to send photos in Base64 encoding.

HTTP Request

PUT https://saia.3dlook.me/api/v2/persons/<id>/?measurements_type=all

URL Parameters

The following parameters should be included in the URL path.

Parameter Description
id The ID of the person created without front and side photo

Request Body

The request body should be a "multipart/form-data" encoded object, containing the following items.

Parameter Type Validation Description
front_image file correct image, filename with image extension front photo of person
side_image file correct image, filename with image extension side photo of person

Create a New Person Single request

import requests

headers = {
    'Authorization': 'APIKey <YOUR_API_KEY_HERE>',
    'Content-Type': 'application/json'
}

payload = {
    'gender': 'female',
    'height': 170,
    'weight': 70.0,
    'front_image': 'base64_decoded_image',
    'side_image': 'base64_decoded_image'
}

response = requests.request('POST', 'https://saia.3dlook.me/api/v2/persons/?measurements_type=all', data=payload, headers=headers)
print(response.text)
curl "https://saia.3dlook.me/api/v2/persons/?measurements_type=all"
  -X POST
  -H "Authorization: APIKey <YOUR_API_KEY_HERE>"
  -d '{
    "gender": "female",
    "height": 170,
    "weight": 70.0,
    "front_image": "base64_decoded_image",
    "side_image": "base64_decoded_image"
}'
var payload = {
    "gender": "female",
    "height": 170,
    "weight": 70.0,
    "front_image": "base64_decoded_image",
    "side_image": "base64_decoded_image"
}

var settings = {
    "async": true,
    "crossDomain": true,
    "url": "https://saia.3dlook.me/api/v2/persons/?measurements_type=all",
    "method": "POST",
    "headers": {
    "Content-Type": "application/json",
        "Authorization": "APIKey <YOUR_API_KEY_HERE>",
        },
    "processData": false,
    "data": JSON.stringify(payload)
}

$.ajax(settings).done(function (response) {
console.log(response);
});

The above command returns JSON structured like this:

{
    "task_set_url": "https://saia.3dlook.me/api/v2/queue/4d563d3f-38ae-4b51-8eab-2b78483b153e/"
}

This endpoint creates a new person, with metadata first and then the partial update with front and side images, with all parameters with front image and side image Base64 encoded.

HTTP Request

POST https://saia.3dlook.me/api/v2/persons/?measurements_type=all

Request Body

The request body should be an "application/json" encoded object, containing the following items.

Parameter Type Validation Description
gender string required, male or female gender of person, male or female
height integer required, >= 150, <= 220 height of person, in cm
weight float required, >= 30, <= 200 weight of person, in kg
front_image string image encoded to Base64 front photo of person
side_image string image encoded to Base64 side photo of person

Partial Update a Specific Person

import requests

headers = {
    'Authorization': 'APIKey <YOUR_API_KEY_HERE>',
    'Content-Type': 'application/json'
}

files={
    'front_image': open('path_to_file', 'rb'),
    'side_image': open('path_to_file', 'rb'),
}
response = requests.request('PATCH', 'https://saia.3dlook.me/api/v2/persons/3/', files=files, headers=headers)
print(response.text)
curl "https://saia.3dlook.me/api/v2/persons/3/"
  -X PATCH
  -H "Authorization: APIKey <YOUR_API_KEY_HERE>"
  -F front_image=@/path/to/files/front_photo.jpg \
  -F side_image=@/path/to/files/side_photo.jpg
var form = new FormData();
form.append("front_image", $('your-input[type=file]')[0].files[0]);
form.append("side_image", $('your-input[type=file]')[0].files[0]);

var settings = {
    "async": true,
    "crossDomain": true,
    "url": "https://saia.3dlook.me/api/v2/persons/3/",
    "method": "PATCH",
    "headers": {
        "Authorization": "APIKey <YOUR_API_KEY_HERE>",
        },
    "processData": false,
    "contentType": false,
    "mimeType": "multipart/form-data",
    "data": form
}

$.ajax(settings).done(function (response) {
console.log(response);
});

The above command returns JSON structured like this:

{
    "front_image": "person/front_image_name.jpg",
    "side_image": "person/side_image_name.jpg"
}

Response also contains header:

This endpoint is required for the partial update of side or front photos, in case where you want to rerun calculation due to the error.

HTTP Request

PATCH https://saia.3dlook.me/api/v2/persons/<id>/

URL Parameters

The following parameters should be included in the URL path.

Parameter Description
id The ID of the person created without front and side photo

Request Body

The request body should be a "multipart/form-data" encoded object, containing the following items.

Parameter Type Validation Description
front_image file correct image, filename with image extension front photo of person
side_image file correct image, filename with image extension side photo of person

Get a Specific Person

import requests

headers = {
    'Authorization': 'APIKey <YOUR_API_KEY_HERE>'
}

response = requests.request('GET', 'https://saia.3dlook.me/api/v2/persons/545/', headers=headers)
print(response.text)
curl "https://saia.3dlook.me/api/v2/persons/545/"
  -H "Authorization: APIKey <YOUR_API_KEY_HERE>"
var settings = {
    "async": true,
    "crossDomain": true,
    "url": "https://saia.3dlook.me/api/v2/persons/545/",
    "method": "GET",
    "headers": {
        "Authorization": "APIKey <YOUR_API_KEY_HERE>",
        },
    "processData": false,
}

$.ajax(settings).done(function (response) {
console.log(response);
});

The above command returns JSON structured like this:

{
  "id": 114622,
  "url": "https://saia.3dlook.me/api/v2/persons/114622/",
  "gender": "male",
  "height": 200,
  "volume_params": {
    "chest": 102.92,
    "waist": 79.64,
    "low_hips": 102.19,
    "high_hips": 91.44,
    "bicep": 32.63,
    "knee": 39.76,
    "ankle": 28.1,
    "wrist": 19.09,
    "calf": 40.2,
    "thigh": 62.43,
    "mid_thigh_girth": 52.88,
    "neck": 40.7,
    "forearm": 28.79,
    "neck_girth": 38.46,
    "neck_girth_relaxed": 34.38,
    "under_bust_girth": 91.97,
    "upper_chest_girth": 103.8,
    "elbow_girth": 29.2,
    "abdomen": 86.78,
    "armscye_girth": 53.29
  },
  "front_params": {
    "soft_validation": {
      "messages": ""
    },
    "body_height": 53.77,
    "outseam": 130.96,
    "outseam_from_upper_hip_level": 96.04,
    "inseam": 86.37,
    "inside_crotch_length_to_mid_thigh": 45,
    "inside_crotch_length_to_knee": 33,
    "inside_crotch_length_to_calf": 23,
    "crotch_length": 35.11,
    "sleeve_length": 69.86,
    "underarm_length": 45.61,
    "legs_distance": 21.67,
    "high_hips": 33.75,
    "hip_height": 108.96,
    "shoulders": 46.01,
    "chest_top": 37.61,
    "jacket_length": 78.15,
    "shoulder_length": 13.94,
    "neck": 14.71,
    "waist": 29.94,
    "waist_to_low_hips": 23.19,
    "waist_to_knees": 70.88,
    "nape_to_waist_centre_back": 51.39,
    "bust_height": 149.63,
    "shoulder_slope": 22.8,
    "shoulder_to_waist": 47.69,
    "side_neck_point_to_armpit": 22.46,
    "back_neck_height": 173.1,
    "back_neck_point_to_wrist_length": 93.55,
    "upper_hip_height": 118.17,
    "waist_height": 132.15,
    "across_back_width": 41.43,
    "outer_ankle_height": 10.66,
    "knee_height": 61.27,
    "across_back_shoulder_width": 47.57,
    "total_crotch_length": 84.24,
    "inside_leg_height": 97.04,
    "neck_length": 10.1,
    "upper_arm_length": 36.88,
    "lower_arm_length": 32.98,
    "upper_hip_to_hip_length": 9.21,
    "back_shoulder_width": 50.67,
    "rise": 27.69,
    "back_neck_to_hip_length": 68.92,
    "torso_height": 79.11,
    "front_crotch_length": 36.14,
    "back_crotch_length": 45.78
  },
  "side_params": {
    "soft_validation": {
      "messages": ""
    },
    "neck_to_chest": 26.21,
    "chest_to_waist": 21.47,
    "waist_to_ankle": 122.73,
    "shoulders_to_knees": 115.7,
    "side_upper_hip_level_to_knee": 59.38,
    "side_neck_point_to_upper_hip": 56.28
  }
}

This endpoint retrieves a specific person with calculated params after all calculation tasks were finished.

HTTP Request

GET https://saia.3dlook.me/api/v2/persons/<id>/

URL Parameters

The following parameters should be included in the URL path.

Parameter Description
id The ID of the person with calculations to retrieve

List All Persons

import requests

headers = {
    'Authorization': 'APIKey <YOUR_API_KEY_HERE>'
}

response = requests.request('GET', 'https://saia.3dlook.me/api/v2/persons/', headers=headers)
print(response.text)
curl "https://saia.3dlook.me/api/v2/persons/"
  -H "Authorization: APIKey <YOUR_API_KEY_HERE>"
var settings = {
    "async": true,
    "crossDomain": true,
    "url": "https://saia.3dlook.me/api/v2/persons/",
    "method": "GET",
    "headers": {
        "Authorization": "APIKey <YOUR_API_KEY_HERE>",
        },
    "processData": false,
}

$.ajax(settings).done(function (response) {
console.log(response);
});

The above command returns JSON structured like this:

{
  "count": 20,
  "next": "https://saia.3dlook.me/api/v2/persons/?page=2",
  "previous": null,
  "results": [
    {
      "id": 114622,
      "url": "https://saia.3dlook.me/api/v2/persons/114622/",
      "gender": "male",
      "height": 200,
      "volume_params": {
        "chest": 102.92,
        "waist": 79.64,
        "low_hips": 102.19,
        "high_hips": 91.44,
        "bicep": 32.63,
        "knee": 39.76,
        "ankle": 28.1,
        "wrist": 19.09,
        "calf": 40.2,
        "thigh": 62.43,
        "mid_thigh_girth": 52.88,
        "neck": 40.7,
        "forearm": 28.79,
        "neck_girth": 38.46,
        "neck_girth_relaxed": 34.38,
        "under_bust_girth": 91.97,
        "upper_chest_girth": 103.8,
        "elbow_girth": 29.2,
        "abdomen": 86.78,
        "armscye_girth": 53.29
      },
      "front_params": {
        "soft_validation": {
          "messages": ""
        },
        "body_height": 53.77,
        "outseam": 130.96,
        "outseam_from_upper_hip_level": 96.04,
        "inseam": 86.37,
        "inside_crotch_length_to_mid_thigh": 45,
        "inside_crotch_length_to_knee": 33,
        "inside_crotch_length_to_calf": 23,
        "crotch_length": 35.11,
        "sleeve_length": 69.86,
        "underarm_length": 45.61,
        "legs_distance": 21.67,
        "high_hips": 33.75,
        "hip_height": 108.96,
        "shoulders": 46.01,
        "chest_top": 37.61,
        "jacket_length": 78.15,
        "shoulder_length": 13.94,
        "neck": 14.71,
        "waist": 29.94,
        "waist_to_low_hips": 23.19,
        "waist_to_knees": 70.88,
        "nape_to_waist_centre_back": 51.39,
        "bust_height": 149.63,
        "shoulder_slope": 22.8,
        "shoulder_to_waist": 47.69,
        "side_neck_point_to_armpit": 22.46,
        "back_neck_height": 173.1,
        "back_neck_point_to_wrist_length": 93.55,
        "upper_hip_height": 118.17,
        "waist_height": 132.15,
        "across_back_width": 41.43,
        "outer_ankle_height": 10.66,
        "knee_height": 61.27,
        "across_back_shoulder_width": 47.57,
        "total_crotch_length": 84.24,
        "inside_leg_height": 97.04,
        "neck_length": 10.1,
        "upper_arm_length": 36.88,
        "lower_arm_length": 32.98,
        "upper_hip_to_hip_length": 9.21,
        "back_shoulder_width": 50.67,
        "rise": 27.69,
        "back_neck_to_hip_length": 68.92,
        "torso_height": 79.11,
        "front_crotch_length": 36.14,
        "back_crotch_length": 45.78
      },
      "side_params": {
        "soft_validation": {
          "messages": ""
        },
        "neck_to_chest": 26.21,
        "chest_to_waist": 21.47,
        "waist_to_ankle": 122.73,
        "shoulders_to_knees": 115.7,
        "side_upper_hip_level_to_knee": 59.38,
        "side_neck_point_to_upper_hip": 56.28
      }
    },
    {
      "id": 114623,
      "url": "https://saia.3dlook.me/api/v2/persons/114623/",
      "gender": "male",
      "height": 200,
      "volume_params": {
        "chest": 102.92,
        "waist": 79.64,
        "low_hips": 102.19,
        "high_hips": 91.44,
        "bicep": 32.63,
        "knee": 39.76,
        "ankle": 28.1,
        "wrist": 19.09,
        "calf": 40.2,
        "thigh": 62.43,
        "mid_thigh_girth": 52.88,
        "neck": 40.7,
        "forearm": 28.79,
        "neck_girth": 38.46,
        "neck_girth_relaxed": 34.38,
        "under_bust_girth": 91.97,
        "upper_chest_girth": 103.8,
        "elbow_girth": 29.2,
        "abdomen": 86.78,
        "armscye_girth": 53.29
      },
      "front_params": {
        "soft_validation": {
          "messages": ""
        },
        "body_height": 53.77,
        "outseam": 130.96,
        "outseam_from_upper_hip_level": 96.04,
        "inseam": 86.37,
        "inside_crotch_length_to_mid_thigh": 45,
        "inside_crotch_length_to_knee": 33,
        "inside_crotch_length_to_calf": 23,
        "crotch_length": 35.11,
        "sleeve_length": 69.86,
        "underarm_length": 45.61,
        "legs_distance": 21.67,
        "high_hips": 33.75,
        "hip_height": 108.96,
        "shoulders": 46.01,
        "chest_top": 37.61,
        "jacket_length": 78.15,
        "shoulder_length": 13.94,
        "neck": 14.71,
        "waist": 29.94,
        "waist_to_low_hips": 23.19,
        "waist_to_knees": 70.88,
        "nape_to_waist_centre_back": 51.39,
        "bust_height": 149.63,
        "shoulder_slope": 22.8,
        "shoulder_to_waist": 47.69,
        "side_neck_point_to_armpit": 22.46,
        "back_neck_height": 173.1,
        "back_neck_point_to_wrist_length": 93.55,
        "upper_hip_height": 118.17,
        "waist_height": 132.15,
        "across_back_width": 41.43,
        "outer_ankle_height": 10.66,
        "knee_height": 61.27,
        "across_back_shoulder_width": 47.57,
        "total_crotch_length": 84.24,
        "inside_leg_height": 97.04,
        "neck_length": 10.1,
        "upper_arm_length": 36.88,
        "lower_arm_length": 32.98,
        "upper_hip_to_hip_length": 9.21,
        "back_shoulder_width": 50.67,
        "rise": 27.69,
        "back_neck_to_hip_length": 68.92,
        "torso_height": 79.11,
        "front_crotch_length": 36.14,
        "back_crotch_length": 45.78
      },
      "side_params": {
        "soft_validation": {
          "messages": ""
        },
        "neck_to_chest": 26.21,
        "chest_to_waist": 21.47,
        "waist_to_ankle": 122.73,
        "shoulders_to_knees": 115.7,
        "side_upper_hip_level_to_knee": 59.38,
        "side_neck_point_to_upper_hip": 56.28
      }
    }
  ]
}

This endpoint retrieves all your existing persons with calculations.

HTTP Request

GET https://saia.3dlook.me/api/v2/persons/

Query Parameters

The following parameters should be included as part of the URL query string.

Parameter Default Description
page A page number within the paginated result set.

Manually Start Calculations of a Specific Person

import requests

headers = {
    'Authorization': 'APIKey <YOUR_API_KEY_HERE>'
}

response = requests.request('GET', 'https://saia.3dlook.me/api/v2/persons/545/calculate/?measurements_type=all', headers=headers)
print(response.text)
curl "https://saia.3dlook.me/api/v2/persons/545/calculate/?measurements_type=all"
  -H "Authorization: APIKey <YOUR_API_KEY_HERE>"
var settings = {
    "async": true,
    "crossDomain": true,
    "url": "https://saia.3dlook.me/api/v2/persons/545/calculate/?measurements_type=all",
    "method": "GET",
    "headers": {
        "Authorization": "APIKey <YOUR_API_KEY_HERE>",
        },
    "processData": false,
}

$.ajax(settings).done(function (response) {
console.log(response);
});

The above command returns JSON structured like this:

{
    "task_set_url": "https://saia.3dlook.me/api/v2/queue/4d563d3f-38ae-4b51-8eab-2b78483b153e/"
}

This endpoint is manually run calculations of all parameters after Partial Update of photos of a specific person. As a result, you will get URL for task_set, where the info can be tracked.

HTTP Request

GET https://saia.3dlook.me/api/v2/persons/<id>/calculate/?measurements_type=all

URL Parameters

The following parameters should be included in the URL path.

Parameter Description
id The ID of the person with calculations to retrieve

Get a Specific Task Set

import requests

headers = {
    'Authorization': "APIKey <YOUR_API_KEY_HERE>"
}

response = requests.request('GET', 'https://saia.3dlook.me/api/v2/queue/6a885ee2-153a-4cc4-9111-fbee31738410/', headers=headers)
print(response.text)
curl "https://saia.3dlook.me/api/v2/queue/6a885ee2-153a-4cc4-9111-fbee31738410/"
  -H "Authorization: APIKey <YOUR_API_KEY_HERE>"
var settings = {
    "async": true,
    "crossDomain": true,
    "url": "https://saia.3dlook.me/api/v2/queue/6a885ee2-153a-4cc4-9111-fbee31738410/",
    "method": "GET",
    "headers": {
        "Authorization": "APIKey <YOUR_API_KEY_HERE>",
        },
    "processData": false,
}

$.ajax(settings).done(function (response) {
console.log(response);
});

The above command returns JSON structured like this:

{
    "is_successful": false,
    "is_ready": false,
    "sub_tasks": [
        {
            "name": "unrecognized_task",
            "status": "PENDING",
            "task_id": "6bbe7942-eadd-4bd2-84c8-c03f9c6a2f7a",
            "message": ""
        },
        {
            "name": "unrecognized_task",
            "status": "PENDING",
            "task_id": "10324eb8-c60f-4b20-baed-9c66d9ca9e66",
            "message": ""
        },
        {
            "name": "unrecognized_task",
            "status": "PENDING",
            "task_id": "10324eb8-c60f-4b20-baed-9c66d9ca9e66",
            "message": ""
        }
    ]
}

Returns information of given task-set:

HTTP Request

GET https://saia.3dlook.me/api/v2/queue/<task_set_id>/

URL Parameters

Parameter Description
task_set_id The id of the task_set to retrieve

Integration

Javascript SDK for SAIA MTM API

SAIA Javascript SDK.

Errors

HTTP Errors

The SAIA API uses the following error codes:

Error Code Meaning
400 Bad Request -- Your request is invalid.
401 Unauthorized -- Your API key is incorrect.
403 Forbidden -- Access to the requested API is forbidden.
404 Not Found -- The specified item could not be found.
406 Not Acceptable -- You requested a non-JSON format.
422 Unprocessable Entity -- One or both of the taken photos could not be processed.
429 Too Many Requests -- You are sending too many requests.
500 Internal Server Error -- A server error occurred. Try again later.
503 Service Unavailable -- We're temporarily offline for maintenance. Please try again later.

Task Errors

Asynс Params Calculation Tasks uses the following error codes:

Application Code Message Meaning
900 The pose is wrong, check your <body_part> The pose of the human body in one or both of the taken photos is wrong and we cannot process the human body.
901 Сan not detect the human body The human body in the photo cannot be detected.
903 Side photo in the front The photo taken to the Front slot was detected to be a Side photo.
904 The body is not full The photo does not contain the whole body.

Soft Validation Errors

Each returned person's JSON could include objects(for Front and Side photos) with recommendation message for users how they can get more accurate calculation results(Soft validation):

Application Code Message Meaning
920 Keep your head straight Head tilt detected.
921 Keep your hands at waist level Hand placement detected at hips or chest levels.
922 Check your <body_part> Minor problem(s) detected with one or multiple body part(s).
923 Selfie pose Minor detected that photo was made with selfie.

How-To

Step-by-step guides for your use cases

Basic SDK flow example

<label for="front_image">
    <input type="file" name="front_image" id="front_image">
</label>

Choose front image:

<label for="side_image">
    <input type="file" name="side_image" id="side_image">
</label>

Choose side image:

<label for="gender">
  <select name="gender" id="gender">
    <option value="male">male</option>
    <option value="female">female</option>
  </select>
</label>

Choose gender:

<label for="height">
  <input type="number" name="height" id="height" value="170">
</label>

<p>Execution status: <span id="status"></span></p>
<button id="start" type="button">START</button>
<pre id="results" class="results"></pre>

Enter height:

<label for="weight">
  <input type="number" name="weight" id="weight" value="80">
</label>

<p>Execution status: <span id="status"></span></p>
<button id="start" type="button">START</button>
<pre id="results" class="results"></pre>

Enter weight:

import SAIA from ‘@3dlook/saia-sdk’;

const frontImage = document.getElementById('front_image');
const sideImage = document.getElementById('side_image');
const gender = document.getElementById('gender');
const height = document.getElementById('height');
const startBtn = document.getElementById('start');
const results = document.getElementById('results');
const status = document.getElementById('status');

const saia = new SAIA({
  key: '<YOUR_API_KEY>',
});

Import SAIA SDK class:

startBtn.addEventListener('click', () => {
  let frontImage64;
  let sideImage64;

  // convert front image to base64
  saia.utils.getBase64(frontImage.files[0])
    .then((base64) => {
      frontImage64 = base64;

      // convert side image to base64
      return saia.utils.getBase64(sideImage.files[0]);
    })
    .then((base64) => {
      sideImage64 = base64;

      // create person with gender, height and images
      return saia.api.person.create({
        gender: gender.value,
        height: height.value,
        frontImage: frontImage64,
        sideImage: sideImage64,
      });
    })
    .then((taskSetId) => {
      status.innerHTML = 'Processing...';

      // check person processing and get the result
      return saia.api.queue.getResults(taskSetId);
    })
    .then((person) => {
      status.innerHTML = 'Finished';


      // print the result out
      results.innerHTML = JSON.stringify(person, null, '  ');
    })
    .catch((e) => {
      console.log(e);
    });
});

Set the start button click event handler to start the flow

One step form wireframe

This form must consist of the following mandatory fields:

One step form wireframe

Height input field(s)

Height must be more or equal to 150cm (4’ 11”) and less or equal to 220cm (7’ 2”).

Min height in cm. Height should be more or equal to 150cm

One step form wireframe

Max height in cm. Height should be less or equal to 220cm

One step form wireframe

Min height in inches. Height should be more or equal to 4’ 11’’

One step form wireframe

Max height in inches. Height should be less or equal to 7’ 2’’

One step form wireframe

/**
 * Convert centimeters value to feet and inches
 *
 * @param {number} cm - centimeters
 * @returns {Object} object with foot-inch values
 */
const cmToFtIn = (cm) => {
  const inches = cm / 2.54;
  const ft = inches / 12;

  return {
    ft: Math.floor(ft),
    in: Math.ceil(inches.toFixed(0) % 12),
  };
};

Function for converting centimeters to foot-inch values:

/**
 * Convert inches to centimeters
 *
 * @param {number} inches - inches
 * @returns {number} centimeters value
 */
const in2cm = inches => inches * 2.54;

Function for converting inches to centimeters:

/**
 * Convert ft to in value
 *
 * @param {number} ft - foot value
 * @returns {number} inch value
 */
const ft2in = ft => ft * 12;

Function for converting feet to inches:

/**
 * Convert ft and in height to cm value
 *
 * @param {number} ft - foot value
 * @param {number} inches - inch value
 */
const getHeightCm = (ft = 0, inches = 0) => {
  return in2cm(ft2in(ft) + parseInt(inches, 10));
};

Function for converting foot-inch value to centimeters

Gender radio buttons

The best practice is to show the outlines of the body according to the specified gender

Gender specified as Female

Gender specified as Female

Gender specified as Male

Gender specified as Male

Slots for front and side photos

1. When the slots are empty

When the slots are empty

In the description of each slot, a user must see the full information about what must be done:

2. User has taken photos

When the slots are empty

Image rotation fix https://gist.github.com/pisarivskiy/b68a5bd3e31c59586f99c60008e6f9eb#file-image-orientation-fix-example-js

$('#load-file').on('change', function () {
  var file = $(this).files[0];

  getOrientation(file)
    .then(function (fixOrientation) {
      return loadPhoto(file, fixOrientation);
    })
    .then(function (file) {
      img.attr('src', file);
    })
    .catch(function (err) {
      console.log(err);
    });
});

This code checks EXIF flag in the image file metadata and rotates it based on this flag. You need to get a blob object from input element with change event.

The result of loadPhoto method (base64 encoded image) can be sent to our API.

If a user fills in the form correctly

user fills in the form correctly

function handleSubtaskErrors(subtasks) {
  const front = subtasks.filter(function (item) { return item.name.indexOf('front_') !== -1; })[0];
  const side = subtasks.filter(function (item) { return item.name.indexOf('side_') !== -1; })[0];

  if (front && front.status === 'FAILURE') {
    frontPhoto.classList.add('error');
  }

  if (side && side.status === 'FAILURE') {
    sidePhoto.classList.add('error');
  }
}

Errors messages and errors validation

If saia.api.queue.getResults returns an error, you could handle it in the following way to properly identify the image that produces the error

Errors messages and errors validation

Errors messages and errors validation

Recommendations: Please retake the photo.

Check if you’ve followed through all of our recommendations:

If a user took a wrong front photo

If a user uploaded a wrong side photo

Recommendations:

Please retake the photo.

Check if you’ve followed through all of our recommendations:

If a user took a wrong side photo

If a user uploaded a wrong side photo

Recommendations:

Please retake the photo.

Check if you’ve followed through all of our recommendations:

Two step form wireframe

The form in can be done in two steps. See the example below:

Mandatory fields for the First Step:

First Step

Mandatory fields for the Second Step:

First Step

Postman Examples