Skip to content

API Reference

Deprecated

This documentation covers Bodygram Estimation API which is now deprecated. Please refer to the Bodygram Platform for the latest documentation on Bodygram's most complete scanning solution.

The schemas of all the JSON objects exchanged via the Body Scanner API are defined using the Protocol Buffer format.

Create Session

The CreateSession API allows you to create new scanning session and to receive its Scanning Session ID (SSID).

POST https://api.bodyscanner.bodygram.com/scanning/v0/create-session

Request body

Protocol buffer schema:

syntax = "proto3";

import "google/protobuf/timestamp.proto";

message CreateScanningSessionRequest {
  // Your unique Client ID, provided by Bodygram
  string client_id = 1;

  // Custom ID provided by the client to refer to this scanning session.
  // The provided ID will be returned as part of all responses relative
  // to this session. There is no constraint on the ID which can be
  // reused in multiple scanning sessions or even omitted.
  string client_scanning_id = 2;

  // Various configurable options about the scanning session.
  message ScanningConfig {
    // Language (ISO 639 2-letters code) in which the scanning instructions
    // must be given. Default to "en" if no code is provided or if the code
    // is not supported.
    string language_code = 1;

    // Whether or not the 3D avatar data should be included in the results of
    // this scanning session.
    bool include_3d_avatar_in_results = 2;
  }
  ScanningConfig scanning_config = 3;
}

Example JSON:

{
  "clientId": "$CLIENT_ID",
  "clientScanningId": "abc123",
  "scanningConfig": {
    "languageCode": "ja",
    "include3dAvatarInResults": true
  }
}

Response body

Protocol buffer schema:

syntax = "proto3";

import "google/protobuf/timestamp.proto";

message CreateScanningSessionResponse {
  // List of possible response bodies. The response will always contain
  // at most one of the following bodies.
  oneof body {
    // Information about the created scanning session.
    ScanningSession scanning_session = 1;

    // Error that occurred when creating the scanning session.
    Error error = 2;
  }

  message ScanningSession {
    // ID issued by Bodygram to refer to this scanning session. This ID
    // is guaranteed to be globally unique.
    string scanning_session_id = 1;

    // The client scanning ID that was provided by the client when the
    // scanning session was created.
    string client_scanning_id = 2;

    // Unix timestamp (in seconds) at which the scanning session will
    // expire.
    google.protobuf.Timestamp expire_at_timestamp = 3;
  }

  message Error {
    // The type of the error that occurred during the creation of the
    // scanning session.
    enum ErrorType {
      ERROR_TYPE_UNSPECIFIED = 0;
      INVALID_CLIENT_ID = 1;
      INVALID_REDIRECT_URL = 2;
      MALFORMED_REQUEST_BODY = 3;
      INTERNAL_ERROR = 4;
    }
    ErrorType error_type = 1;

    // Error message localized in the language specified in the session.
    string message = 2;
  }
}

Example successful JSON response body:

{
    "scanningSession": {
        "scanningSessionId": "$GENERATED_SESSION_ID",
        "clientScanningId": "abc123",
        "expireAtTimestamp": "2022-04-01T07:44:07.746059293Z"
    }
}

Example JSON error body:

{
    "error": {
        "errorType": "MALFORMED_REQUEST",
        "message": "The request body does not appear to be valid JSON structure"
    }
}

Typically, an unsuccessful response indicates that either the provided client ID is incorrect or missing, or that the request body is invalid. Key message provides a detailed (developer intended) explanation of what the error is about. The message is displayed in English by default unless specified otherwise in the scanningConfig. Key errorType maps to the enum values defined in the Proto schema. See create-session in the Protobuf section of this document for the full specification.

Get Scan Results

The GetScanResults API allows you to get the results from a scanning session. The response can be of three forms:

  • Success: the estimated measurements are returned.
  • Pending: the user has not yet completed the entire flow.
  • Error: the flow didn't complete successfully.
GET https://api.bodyscanner.bodygram.com/scanning/v0/results/$SSID

Request

The only parameter is the Scanning Session ID (SSID) to be passed in the path.

Response

Protocol buffer schema:

syntax = "proto3";

import "google/protobuf/timestamp.proto";

// Each measurement type represents a specific body measurement.
enum MeasurementType {
  MEASUREMENT_TYPE_UNSPECIFIED = 0;

  // The total muscle mass of the subject.
  SKELETAL_MUSCLE_MASS = 1;

  // The percentage of body fat mass compared to the total mass of the subject.
  BODY_FAT_PERCENTAGE = 2;

  // The total mass of the subject.
  WEIGHT = 3;

  // Definition: Neck 
  // see developpers.bodygram.com/measurements/defitions.
  NECK_GIRTH = 4;

  // Definition: Neck base 
  // see developpers.bodygram.com/measurements/defitions.
  NECK_BASE_GIRTH = 5;

  // Definition: Shoulder width 
  // see developpers.bodygram.com/measurements/defitions.
  ACROSS_BACK_SHOULDER_WIDTH = 6;

  // Definition: Upper arm  
  // see developpers.bodygram.com/measurements/defitions.
  UPPER_ARM_GIRTH_R = 7;

  // Definition: Sleeve length
  // see developpers.bodygram.com/measurements/defitions. 
  BACK_NECK_POINT_TO_WRIST_R = 8;

  // Definition: Outer arm length   
  // see developpers.bodygram.com/measurements/defitions.
  OUTER_ARM_LENGTH_R = 9;

  // Definition: Bust
  // see developpers.bodygram.com/measurements/defitions.
  BUST_GIRTH = 10;

  // Definition: Under bust 
  // see developpers.bodygram.com/measurements/defitions.
  UNDER_BUST_GIRTH = 11;

  // Definition: Waist  
  // see developpers.bodygram.com/measurements/defitions.
  WAIST_GIRTH = 12;

  // Definition: Belly waist        
  // see developpers.bodygram.com/measurements/defitions.
  BELLY_WAIST_GIRTH = 13;

  // Definition: Wrist  
  // see developpers.bodygram.com/measurements/defitions.
  WRIST_GIRTH_R = 14;

  // Definition: Back (to waist) length 
  // see developpers.bodygram.com/measurements/defitions.
  BACK_NECK_POINT_TO_WAIST = 15;

  // Definition: Top hip    
  // see developpers.bodygram.com/measurements/defitions.
  TOP_HIP_GIRTH = 16;

  // Definition: Hop    
  // see developpers.bodygram.com/measurements/defitions.
  HIP_GIRTH = 17;

  // Definition: Thigh  
  // see developpers.bodygram.com/measurements/defitions.
  THIGH_GIRTH_R = 18;

  // Definition: Mid-thigh  
  // see developpers.bodygram.com/measurements/defitions.
  MID_THIGH_GIRTH_R = 19;

  // Definition: Knee
  // see developpers.bodygram.com/measurements/defitions.
  KNEE_GIRTH_R = 20;

  // Definition: Calf
  // see developpers.bodygram.com/measurements/defitions.
  CALF_GIRTH_R = 21;

  // Definition: Outside leg length     
  // see developpers.bodygram.com/measurements/defitions.
  OUTSIDE_LEG_LENGTH_R = 22;

  // Definition: Inside leg height  
  // see developpers.bodygram.com/measurements/defitions.
  INSIDE_LEG_HEIGHT = 23;

  // Definition: Inside leg length  
  // see developpers.bodygram.com/measurements/defitions.
  INSIDE_LEG_LENGTH_R = 24;

  // Definition: Outseam    
  // see developpers.bodygram.com/measurements/defitions.
  OUTSEAM_R = 25;

  // Definition: Outer ankle height 
  // see developpers.bodygram.com/measurements/defitions.
  OUTER_ANKLE_HEIGHT_R = 26;

  // Definition: Full body length       
  // see developpers.bodygram.com/measurements/defitions.
  BACK_NECK_POINT_TO_GROUND_CONTOURED = 27;

  // Definition: Knee height        
  // see developpers.bodygram.com/measurements/defitions.
  KNEE_HEIGHT_R = 28;

  // Definition: Bust height    
  // see developpers.bodygram.com/measurements/defitions.
  BUST_HEIGHT = 29;

  // Definition: Hip height 
  // see developpers.bodygram.com/measurements/defitions.
  HIP_HEIGHT = 30;

  // Definition: Waist height   
  // see developpers.bodygram.com/measurements/defitions.
  WAIST_HEIGHT = 31;

  // Definition: Top hip height 
  // see developpers.bodygram.com/measurements/defitions.
  TOP_HIP_HEIGHT = 32;

  // Definition: Back neck height   
  // see developpers.bodygram.com/measurements/defitions.
  BACK_NECK_HEIGHT = 33;

  // Definition: Forearm    
  // see developpers.bodygram.com/measurements/defitions.
  FOREARM_GIRTH_R = 34;

  // Definition: Shoulder to elbow      
  // see developpers.bodygram.com/measurements/defitions.
  SHOULDER_TO_ELBOW_R = 35;

  // Definition: Belly waist height 
  // see developpers.bodygram.com/measurements/defitions.
  BELLY_WAIST_HEIGHT = 36;

  // Definition: Belly waist width  
  // see developpers.bodygram.com/measurements/defitions.
  BELLY_WAIST_WIDTH = 37;

  // Definition: Belly waist depth      
  // see developpers.bodygram.com/measurements/defitions.
  BELLY_WAIST_DEPTH = 38;

  // The age of the subject.
  AGE = 39;

  // The biological gender of the subject.
  GENDER = 40;

  // The total height of the subject.
  HEIGHT = 41;
}

message BodyMeasurement {
  MeasurementType measurement_type = 1;

  // Value of the body measurement. The unit of the value depends on
  // the type of the measurement.
  int64 value = 2;

  enum UnitType {
    UNIT_TYPE_UNSPECIFIED = 0;

    // The value is a length expressed in millimeters.
    // Example: 123456 = 123456 millimeters.
    MILLIMETERS = 1;

    // The value is a weight expressed in grams.
    // Example: 123456 = 123456 grams.
    GRAMS = 2;

    // The value is a percentage multiplied by 10^4.
    // Example: 123456 = 12.3456%
    PERCENTAGE_E4 = 3;

    // The value is an duration expressed in years.
    // Example: 42 = 42 years.
    YEARS = 4;

    // MALE = 1; FEMALE = 2;
    GENDER = 5;
  }
  UnitType unit = 3;
}

enum AngleUnitType {
  ANGLE_UNIT_TYPE_NOT_SPECIFIED = 0;
  ANGLE_UNIT_TYPE_DEGREES = 1;
  ANGLE_UNIT_TYPE_RADIANS = 2;
}

message ScanningMeasurementResults {
  repeated BodyMeasurement measurements = 1;

  // 3D Avatar data.
  message Avatar {
    // Format of the 3d avatar data.
    oneof format {
      MeshVerticesOnly mesh_vertices_only = 1;

      // Other avatar formats may be added.
    }
    message MeshVerticesOnly {
      // Vertex data of the 3d mesh. These can be used with associated index buffer
      // for drawing indexed triangles (for example via glDrawElements in the OpenGL spec).
      repeated float vertices = 1;
    }
  }
  Avatar avatar = 2;

  // Posture data obtained from the submitted photos.
  message Posture {
    // Front contains posture information from the submitted front photo.
    message Front {
      // Name of the measurement.
      enum MeasurementName {
        MEASUREMENT_NAME_NOT_SPECIFIED = 0;
        EAR = 1;
        SHOULDER = 2;
        TOP_HIP = 3;
        FOOT = 4;
      }
      message Angle {
        MeasurementName name = 1;

        // Measured angle.
        double value = 2;

        // Unit of measurement of the angle.
        AngleUnitType unit = 3;
      }
      repeated Angle angles = 1;

      message Line {
        // Name of the measurement.
        MeasurementName name = 1;

        // Point represents a start or end of a line.
        message Point {
          double x = 1;
          double y = 2;
        }
        repeated Point points = 2;
      }
      repeated Line lines = 2;
    }
    Front front = 1;

    // Right contains posture information from the submitted right/side photo.
    message Right {
      // Name of the measurement.
      enum MeasurementName {
        MEASUREMENT_NAME_NOT_SPECIFIED = 0;
        BODY_LINE = 1;
        BACK_WAIST_LINE = 2;
      }
      message Angle {
        MeasurementName name = 1;

        // Measured angle.
        repeated double angles = 2;

        // Unit of measurement of the angles.
        AngleUnitType unit = 3;
      }
      repeated Angle angles = 1;

      message Line {
        // Name of the measurement.
        MeasurementName name = 1;

        // Point represents a start or end of a line.
        message Point {
          double x = 1;
          double y = 2;
        }
        repeated Point points = 2;
      }
      repeated Line lines = 2;
    }
    Right right = 2;
  }
  Posture posture = 3;
}

message ScanningResults {
  // The scanning session ID to which these results belong.
  string scanning_session_id = 1;

  // The client scanning ID that was provided by the client when the
  // scanning session was created.
  string client_scanning_id = 2;


  // List of possible response bodies. The response will always contain
  // at most one of the following bodies.
  oneof body {
    // The scanning results.
    ScanningMeasurementResults results = 3;

    // Pending indicates that the scanning session has not completed yet.
    Pending pending = 4;

    // Error that might have occurred during the scanning session
    Error error = 5;
  }

  message Pending {
    // Expiration timestamp of the requesting session
    google.protobuf.Timestamp expire_at_timestamp = 1;
  }

  message Error {
    // The type of the error.
    enum ErrorType {
      ERROR_TYPE_UNSPECIFIED = 0;
      INVALID_USER_INPUT = 1;
      SESSION_EXPIRED = 2;
      USER_INPUT_NOT_SUBMITTED = 3;
      ABORTED = 4;
      INTERNAL_ERROR = 5;
      INVALID_SESSION_ID = 6;
    }
    ErrorType error_type = 1;

    // Error message localized in the language that was specified when
    // the scanning session was created.
    string message = 2;
  }
}

Example successful JSON response body:

{
  "scanningSessionId": "$SESSION_ID",
  "clientScanningId": "abc123",
  "results": {
    "measurements": [
      {
        "measurementType": "BODY_FAT_PERCENTAGE",
        "value": "141250",
        "unit": "PERCENTAGE_E4"
      },
      {
        "measurementType": "SKELETAL_MUSCLE_MASS",
        "value": "12500",
        "unit": "GRAMS"
      },
      {
        "measurementType": "ACROSS_BACK_SHOULDER_WIDTH",
        "value": "440",
        "unit": "MILLIMETERS"
      },
      {
        "measurementType": "BACK_NECK_HEIGHT",
        "value": "1422",
        "unit": "MILLIMETERS"
      },
      {
        "measurementType": "BACK_NECK_POINT_TO_GROUND_CONTOURED",
        "value": "1449",
        "unit": "MILLIMETERS"
      },
      {
        "measurementType": "BACK_NECK_POINT_TO_WAIST",
        "value": "429",
        "unit": "MILLIMETERS"
      },
      {
        "measurementType": "BACK_NECK_POINT_TO_WRIST_R",
        "value": "816",
        "unit": "MILLIMETERS"
      },
      {
        "measurementType": "BELLY_WAIST_GIRTH",
        "value": "1047",
        "unit": "MILLIMETERS"
      },
      {
        "measurementType": "BELLY_WAIST_HEIGHT",
        "value": "973",
        "unit": "MILLIMETERS"
      },
      {
        "measurementType": "BUST_GIRTH",
        "value": "1191",
        "unit": "MILLIMETERS"
      },
      {
        "measurementType": "BUST_HEIGHT",
        "value": "1130",
        "unit": "MILLIMETERS"
      },
      {
        "measurementType": "CALF_GIRTH_R",
        "value": "440",
        "unit": "MILLIMETERS"
      },
      {
        "measurementType": "FOREARM_GIRTH_R",
        "value": "301",
        "unit": "MILLIMETERS"
      },
      {
        "measurementType": "HIP_GIRTH",
        "value": "1112",
        "unit": "MILLIMETERS"
      },
      {
        "measurementType": "HIP_HEIGHT",
        "value": "821",
        "unit": "MILLIMETERS"
      },
      {
        "measurementType": "INSIDE_LEG_HEIGHT",
        "value": "705",
        "unit": "MILLIMETERS"
      },
      {
        "measurementType": "INSIDE_LEG_LENGTH_R",
        "value": "616",
        "unit": "MILLIMETERS"
      },
      {
        "measurementType": "KNEE_GIRTH_R",
        "value": "392",
        "unit": "MILLIMETERS"
      },
      {
        "measurementType": "KNEE_HEIGHT_R",
        "value": "432",
        "unit": "MILLIMETERS"
      },
      {
        "measurementType": "MID_THIGH_GIRTH_R",
        "value": "523",
        "unit": "MILLIMETERS"
      },
      {
        "measurementType": "NECK_BASE_GIRTH",
        "value": "431",
        "unit": "MILLIMETERS"
      },
      {
        "measurementType": "NECK_GIRTH",
        "value": "412",
        "unit": "MILLIMETERS"
      },
      {
        "measurementType": "OUTER_ANKLE_HEIGHT_R",
        "value": "90",
        "unit": "MILLIMETERS"
      },
      {
        "measurementType": "OUTER_ARM_LENGTH_R",
        "value": "584",
        "unit": "MILLIMETERS"
      },
      {
        "measurementType": "OUTSEAM_R",
        "value": "915",
        "unit": "MILLIMETERS"
      },
      {
        "measurementType": "OUTSIDE_LEG_LENGTH_R",
        "value": "1005",
        "unit": "MILLIMETERS"
      },
      {
        "measurementType": "SHOULDER_TO_ELBOW_R",
        "value": "341",
        "unit": "MILLIMETERS"
      },
      {
        "measurementType": "THIGH_GIRTH_R",
        "value": "654",
        "unit": "MILLIMETERS"
      },
      {
        "measurementType": "TOP_HIP_GIRTH",
        "value": "996",
        "unit": "MILLIMETERS"
      },
      {
        "measurementType": "TOP_HIP_HEIGHT",
        "value": "907",
        "unit": "MILLIMETERS"
      },
      {
        "measurementType": "UNDER_BUST_GIRTH",
        "value": "996",
        "unit": "MILLIMETERS"
      },
      {
        "measurementType": "UPPER_ARM_GIRTH_R",
        "value": "360",
        "unit": "MILLIMETERS"
      },
      {
        "measurementType": "WAIST_GIRTH",
        "value": "1021",
        "unit": "MILLIMETERS"
      },
      {
        "measurementType": "WAIST_HEIGHT",
        "value": "993",
        "unit": "MILLIMETERS"
      },
      {
        "measurementType": "WRIST_GIRTH_R",
        "value": "175",
        "unit": "MILLIMETERS"
      },
      {
        "measurementType": "WEIGHT",
        "value": "65000",
        "unit": "GRAMS"
      },    
      {
        "measurementType": "AGE",
        "value": "42",
        "unit": "YEARS"
      },
      {
        "measurementType": "GENDER",
        "value": "1",
        "unit": "GENDER"
      },
      {
        "measurementType": "HEIGHT",
        "value": "1750",
        "unit": "MILLIMETERS"
      }
    ],
    "avatar": {
      "meshVerticesOnly": {
        "vertices": [
          0.30484238,
          1.0596719,
          -0.047099218,
          0.30903065,
          ... // data truncated for brevity
        ]
      }
    },
    "posture": {
      "front": {
        "angles": [
          {
            "name": "EAR",
            "value": -0.6028661439063512,
            "unit": "ANGLE_UNIT_TYPE_DEGREES"
          },
          {
            "name": "FOOT",
            "value": -1.8401952563928035,
            "unit": "ANGLE_UNIT_TYPE_DEGREES"
          },
          {
            "name": "SHOULDER",
            "value": 0.7716136787360028,
            "unit": "ANGLE_UNIT_TYPE_DEGREES"
          },
          {
            "name": "TOP_HIP",
            "value": -0.8955518377775888,
            "unit": "ANGLE_UNIT_TYPE_DEGREES"
          }
        ],
        "lines": [
          {
            "name": "EAR",
            "points": [
              {
                "x": 621,
                "y": 435
              },
              {
                "x": 487,
                "y": 435
              }
            ]
          },
          {
            "name": "FOOT",
            "points": [
              {
                "x": 653.5,
                "y": 1625.5
              },
              {
                "x": 404.5,
                "y": 1617.5
              }
            ]
          },
          {
            "name": "SHOULDER",
            "points": [
              {
                "x": 700,
                "y": 577
              },
              {
                "x": 403,
                "y": 581
              }
            ]
          },
          {
            "name": "TOP_HIP",
            "points": [
              {
                "x": 668.5999999999999,
                "y": 977
              },
              {
                "x": 431.9,
                "y": 973.3
              }
            ]
          }
        ]
      },
      "right": {
        "angles": [
          {
            "name": "BODY_LINE",
            "angles": [
              4.030958289984682,
              2.577491122049281,
              -6.133249064599326,
              6.568764121821118
            ],
            "unit": "ANGLE_UNIT_TYPE_DEGREES"
          },
          {
            "name": "BACK_WAIST_LINE",
            "angles": [
              14.036243467926468,
              5.194428907734803,
              -7.532601400947371
            ],
            "unit": "ANGLE_UNIT_TYPE_DEGREES"
          }
        ],
        "lines": [
          {
            "name": "BACK_WAIST_LINE",
            "points": [
              {
                "x": 457,
                "y": 942
              },
              {
                "x": 469,
                "y": 894
              },
              {
                "x": 471,
                "y": 872
              },
              {
                "x": 455,
                "y": 751
              }
            ]
          },
          {
            "name": "BODY_LINE",
            "points": [
              {
                "x": 527,
                "y": 1628
              },
              {
                "x": 548,
                "y": 1330
              },
              {
                "x": 562,
                "y": 1019
              },
              {
                "x": 513,
                "y": 563
              },
              {
                "x": 532,
                "y": 398
              }
            ]
          }
        ]
      }
    }
  }
}

Example JSON pending body:

{
  "scanningSessionId": "$SESSION_ID",
  "clientScanningId": "abc123",
  "pending": {
    "expireAtTimestamp": "2022-04-01T06:18:53.486870Z"
  }
}

In this case, this just means the request is still processing; simply try again in a couple of seconds.

Example JSON error body:

{
    "error": {
        "errorType": "USER_INPUT_NOT_SUBMITTED",
        "message": "Measurement data and photos have not yet been submitted"
    }
}

In this example, a request was made for results before the user had submitted their information and photos.

3D Avatar data

In the example success response above there is a property called avatar with the following structure:

"avatar": {
      "meshVerticesOnly": {
        "vertices": [
          0.30484238,
          1.0596719,
          -0.047099218,
          0.30903065,
          ... // data truncated for brevity
        ]
      }
    }

In this example the vertices array contains a unique list of all generated vertices for the generated 3d avatar. This array is unique to the measurements of the request. In order to render this avatar, indexes are required to draw triangles using the vertices. In the case of only vertices, the index data is static, and independent of the vertex data. This is provided separately, and can be found here. How to render this data depends on your graphics API/library of choice. In the case of WebGL, a simple explanation of indexed rendering can be found here.

Posture

Posture Angle Definition
  • Landmarks in front image
  • EAR : tragion (ISO 8559-1 2017, 3.1.3)
  • SHOULDER : shoulder point (ISO 8559-1 2017, 3.1.1)
  • TOP_HIP : highest point of the hip bone (ISO 8559-1 2017, 3.1.16)
  • FOOT : Ground level used to measure the angular offset compared to other angles.
  • Angles in front image
  • Counterclockwise angle of each landmark pair (left to right in the image, right to left on the body) from horizontal line.

posture_angle_front

Posture Line Definition
  • Landmarks in right image
  • BODY_LINE :
    • 0 : outer ankle point (ISO 8559-1 2017, 3.1.18)
    • 1 : The center of knee girth (ISO 8559-1 2017, 5.3.22)
    • 2 : highest point of the hip bone (ISO 8559-1 2017, 3.1.16)
    • 3 : shoulder point (ISO 8559-1 2017, 3.1.1)
    • 4 : tragion (ISO 8559-1 2017, 3.1.3)
  • BACK_WAIST_LINE :
    • 0 : back most point of top hip girth (ISO 8559-1 2017, 5.3.13)
    • 1 : back most point of belly waist girth. (Horizontal girth through belly button.)
    • 2 : back most point of waist girth (ISO 8559-1 2017, 5.3.10)
    • 3 : back most point of under bust girth (ISO 8559-1 2017, 5.3.8)
  • Angles in right image
  • Clockwise angle of connected two landmarks (lower to higher) from vertical line.

posture_line_right