The COCO keypoint format: 17 keypoints, order, and skeleton.

Everything you need to read or write COCO person-keypoint annotations: the exact keypoint order, the official skeleton pairs, what the visibility flags mean, and worked JSON examples. Bookmark-grade; no scrolling through a tutorial to find the list.

The 17 keypoints

Keypoint order

The keypoints array is 0-based, but the skeleton pairs reference 1-based ids — the most common off-by-one in pose tooling. Both are listed. “Left” always means the subject’s left, which appears on the viewer’s right in a front-facing image.

Array index (0-based)Skeleton id (1-based)NameSide
01nose
12left_eyeleft
23right_eyeright
34left_earleft
45right_earright
56left_shoulderleft
67right_shoulderright
78left_elbowleft
89right_elbowright
910left_wristleft
1011right_wristright
1112left_hipleft
1213right_hipright
1314left_kneeleft
1415right_kneeright
1516left_ankleleft
1617right_ankleright
1234567891011121314151617

Numbered with 1-based skeleton ids

The skeleton

The official 19 skeleton pairs

Each pair connects two keypoints by their 1-based ids. This is the canonical list from the COCO annotations, verbatim:

"skeleton": [
  [16,14], [14,12], [17,15], [15,13], [12,13], [6,12], [7,13], [6,7], [6,8], [7,9], [8,10], [9,11], [2,3], [1,2], [1,3], [2,4], [3,5], [4,6], [5,7]
]
Visibility flags

What v = 0, 1, 2 mean

Keypoints are stored as flat [x1, y1, v1, x2, y2, v2, …] triplets — 51 numbers for a person. The third value of each triplet is the visibility flag:

v = 0

Not labeled

x and y are 0; the point was not annotated at all.

v = 1

Labeled, not visible

The point has coordinates but is occluded (e.g. a hip under a coat).

v = 2

Labeled and visible

The point is annotated and visible in the image.

num_keypoints on the annotation counts the labeled points — those with v > 0.

Putting it together

The category and annotation JSON

The category declares the names and skeleton; each annotation carries the triplets. A minimal, valid pair:

// categories[]
{
  "id": 1,
  "name": "person",
  "supercategory": "person",
  "keypoints": [
    "nose", "left_eye", "right_eye",
    "left_ear", "right_ear",
    "left_shoulder", "right_shoulder",
    "left_elbow", "right_elbow",
    "left_wrist", "right_wrist",
    "left_hip", "right_hip",
    "left_knee", "right_knee",
    "left_ankle", "right_ankle"
  ],
  "skeleton": [
    [16,14],[14,12],[17,15],[15,13],
    [12,13],[6,12],[7,13],[6,7],
    [6,8],[7,9],[8,10],[9,11],
    [2,3],[1,2],[1,3],[2,4],
    [3,5],[4,6],[5,7]
  ]
}
// annotations[]
{
  "id": 42,
  "image_id": 7,
  "category_id": 1,
  "num_keypoints": 3,
  "keypoints": [
    412, 143, 2,   // nose: visible
    431, 128, 2,   // left_eye: visible
    398, 129, 1,   // right_eye: occluded
    0,   0,   0,   // left_ear: not labeled
    // … one [x, y, v] triplet per
    // keypoint, 17 in total
  ],
  "bbox": [372, 94, 118, 340],
  "iscrowd": 0,
  "area": 40120
}
Annotate in this format

Skip the conversion scripts.

DataTorch speaks this format natively: define the keypoints and skeleton on a label, annotate point-by-point in the browser with a live skeleton overlay, and import or export COCO keypoints — visibility flags included.

See the keypoint toolStart free

The annotation platform for specialized imagery — review, score, and share datasets your team works from.

Platform

PlatformImaging labsEnterprisePricing

© 2026 DataTorch. All rights reserved.