# 이미지 얼굴 인식



이미지 한 장에서 사람 얼굴을 찾아 얼굴마다 위치(사각형 좌표)와 눈·코·입꼬리 좌표, 인식 점수를 돌려줍니다.



인증: Authorization: Bearer $APICK_API_KEY

본문 있는 REST 요청: multipart/form-data. GET 본문 및 MCP JSON-RPC 규격은 해당 명세를 따릅니다.

인증키는 서버에 보관하세요. 모든 예제는 정적 자료입니다.



## POST /rest/face_detection 응답 필드

- `data` (object): 요청 처리 결과 묶음입니다. 조회한 값·작업 상태·오류 설명이 이 안에 들어 있으며, 실제 하위 필드 구성은 서비스마다 다릅니다. 값이 없으면 null·빈 배열·필드 생략 중 해당 서비스의 규칙을 따릅니다.

- `data.result` (array): 조회 결과 본문입니다. 서비스가 찾은 실제 데이터가 들어 있으며, 자료가 없거나 조회에 실패하면 null이거나 필드가 생략됩니다.

- `data.result[].landmark` (array): 얼굴 기준점 5개의 [x, y] 좌표입니다. 순서는 왼쪽 눈, 오른쪽 눈, 코, 왼쪽 입꼬리, 오른쪽 입꼬리입니다.

- `data.result[].height` (integer): 원본 이미지의 높이(픽셀)입니다. 이미지·영상의 세로 크기(픽셀)입니다. width와 함께 원본 비율을 계산할 수 있습니다.

- `data.result[].width` (integer): 원본 이미지의 너비(픽셀)입니다. 이미지·영상의 가로 크기(픽셀)입니다. 화면 배치 전에 원본 비율을 확인하세요.

- `data.result[].det_score` (number): 얼굴일 가능성 0~1. 1에 가까울수록 확실한 얼굴입니다. 숫자로 오며, 단위·범위는 같은 응답의 다른 필드나 이 문서의 설명을 확인하세요.

- `data.result[].face_crop` (array): 얼굴 사각형의 [[왼쪽 위 x, y], [오른쪽 아래 x, y]] 좌표입니다. 사진을 얼굴 기준으로 자를 때 씁니다.

- `data.success` (integer): 업무 처리 결과 코드입니다. 1은 정상 결과, 0은 실패 또는 무료 응답입니다. 서비스에 따라 2·3처럼 추가 코드를 쓰므로 같은 응답의 status·msg·error 필드도 함께 확인하세요.

- `api` (object): API 호출 메타데이터입니다. 이번 요청의 서버 처리 성공 여부(api.success), 실제 차감 포인트(api.cost), 결제 기록 ID(api.pl_id)를 담습니다. 처리 시간(api.ms)은 응답에 포함된 경우에만 제공됩니다. 업무 결과는 data에서 확인합니다.

- `api.success` (boolean): API 서버가 이번 요청을 정상 처리했는지 여부입니다. true여도 업무 결과가 실패일 수 있으므로 data.success·data.status와 함께 판단합니다. 인증 실패·잘못된 입력·서버 오류 응답에서는 false입니다.

- `api.cost` (integer): 이번 호출에서 실제로 차감된 포인트입니다. 유료 성공 응답에서만 단가만큼 차감되며, 실패·무료 조회·같은 요청의 멱등 재전송은 0입니다. 화면의 표시 단가와 실제 차감액이 다를 수 있으므로 정산은 이 값을 기준으로 합니다.

- `api.ms` (integer): 서버가 요청을 받아 응답 본문을 만들기까지 걸린 처리 시간(밀리초)입니다. 네트워크 왕복 시간과 클라이언트 대기 시간은 포함되지 않습니다.

- `api.pl_id` (integer): 포인트 차감 기록 ID입니다. 차감이 발생한 호출에만 값이 있으며, 과금 내역을 문의할 때 이 번호를 사용합니다. 무과금 응답은 -1·null이거나 필드가 생략됩니다.

## API 요청: POST /rest/face_detection



### 입력

- `image` (file, 필수): 분석할 이미지 파일입니다. JPG·PNG·WEBP를 지원하며, 파일 크기·해상도 제한은 요청 표를 확인하세요.

- `threshold` (string, 선택): 얼굴 추출 민감도 (범위: 0 ~ 0.9, 기본값 0.5, 높을수록 정확한 얼굴만 추출)

- `use_feature` (string, 선택): 얼굴 특징 정보를 응답에 포함할지 정합니다. 1은 포함, 0은 미포함(기본값)입니다. 특징 정보가 필요 없는 경우 0으로 두어 응답을 줄이세요.



### 응답 명세

```json

{
  "type": "object",
  "properties": {
    "data": {
      "type": "object",
      "properties": {
        "result": {
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "landmark": {
                "type": "array",
                "items": {
                  "type": "array",
                  "items": {
                    "type": "number"
                  }
                },
                "description": "얼굴 기준점 5개의 [x, y] 좌표입니다. 순서는 왼쪽 눈, 오른쪽 눈, 코, 왼쪽 입꼬리, 오른쪽 입꼬리입니다."
              },
              "height": {
                "type": "integer",
                "description": "원본 이미지의 높이(픽셀)입니다."
              },
              "width": {
                "type": "integer",
                "description": "원본 이미지의 너비(픽셀)입니다."
              },
              "det_score": {
                "type": "number",
                "description": "얼굴일 가능성 0~1. 1에 가까울수록 확실한 얼굴입니다."
              },
              "face_crop": {
                "type": "array",
                "items": {
                  "type": "array",
                  "items": {
                    "type": "number"
                  }
                },
                "description": "얼굴 사각형의 [[왼쪽 위 x, y], [오른쪽 아래 x, y]] 좌표입니다. 사진을 얼굴 기준으로 자를 때 씁니다."
              }
            }
          },
          "description": "찾은 얼굴 목록입니다. 얼굴이 없으면 빈 배열입니다."
        },
        "success": {
          "type": "integer",
          "description": "처리 결과입니다. 1: 성공(과금), 0: 실패, 3: 시간 초과(과금 없음)."
        }
      },
      "description": "인식 결과"
    },
    "api": {
      "type": "object",
      "properties": {
        "success": {
          "type": "boolean",
          "description": "요청을 정상 처리했는지 여부입니다."
        },
        "cost": {
          "type": "integer",
          "description": "이번 요청에서 차감된 포인트입니다."
        },
        "ms": {
          "type": "integer",
          "description": "처리 시간(밀리초)입니다."
        },
        "pl_id": {
          "type": "integer",
          "description": "결제 기록 번호입니다. 문의할 때 함께 알려 주세요."
        }
      },
      "description": "호출 공통 정보"
    }
  }
}

```

### 정적 응답 예시

```json

{
  "data": {
    "result": [
      {
        "landmark": [
          [
            429.3706970214844,
            280.9442138671875
          ],
          [
            458.5393371582031,
            280.26409912109375
          ],
          [
            443.2686462402344,
            295.4951171875
          ],
          [
            433.3480224609375,
            311.8315124511719
          ],
          [
            455.7586669921875,
            311.30450439453125
          ]
        ],
        "height": 472,
        "width": 742,
        "det_score": 0.8643505573272705,
        "face_crop": [
          [
            424.3706970214844,
            275.26409912109375
          ],
          [
            463.5393371582031,
            316.8315124511719
          ]
        ]
      }
    ],
    "success": 1
  },
  "api": {
    "success": true,
    "cost": 3,
    "ms": 475,
    "pl_id": 108609
  }
}

```

### curl

```curl

curl --fail-with-body --request POST 'https://apick.app/rest/face_detection' \
  --header "Authorization: Bearer $APICK_API_KEY" \
  --form 'image=@./profile.jpg'

```

### Node.js (서버 ESM)

```javascript

import { readFile } from "node:fs/promises";
const form = new FormData();
form.append("image", new Blob([await readFile("./profile.jpg")]), "profile.jpg");
const response = await fetch("https://apick.app/rest/face_detection", {
  method: "POST",
  headers: { Authorization: "Bearer " + process.env.APICK_API_KEY },
  body: form,
  signal: AbortSignal.timeout(120_000),
});
if (!response.ok) throw new Error(`HTTP ${response.status}: ${await response.text()}`);
const result = await response.json();
console.log(result);

```

### python

```python

import os
import requests
parts = [
    ("image", ("profile.jpg", open("./profile.jpg", "rb"))),
]
response = requests.request("POST", "https://apick.app/rest/face_detection",
    headers={"Authorization": "Bearer " + os.environ["APICK_API_KEY"]},
    files=parts,
    timeout=(10, 120))
response.raise_for_status()
result = response.json()
print(result)

```

### php

```php

<?php
$headers = ["Authorization: Bearer " . getenv("APICK_API_KEY")];
$form = [
    'image' => new CURLFile('./profile.jpg'),
];
$curl = curl_init('https://apick.app/rest/face_detection');
curl_setopt_array($curl, [
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_HTTPHEADER => $headers,
    CURLOPT_POSTFIELDS => $form,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_TIMEOUT => 120,
]);
$body = curl_exec($curl);
if ($body === false) { throw new RuntimeException(curl_error($curl)); }
$status = curl_getinfo($curl, CURLINFO_HTTP_CODE);
curl_close($curl);
if ($status >= 400) { throw new RuntimeException($body); }
$result = json_decode($body, true, 512, JSON_THROW_ON_ERROR);
print_r($result);

```

## 사용 예시 1. 프로필 사진에 얼굴이 하나인지 확인

증명사진·프로필처럼 한 명만 있어야 하는 사진을 검사합니다.

```bash

curl --fail-with-body --request POST 'https://apick.app/rest/face_detection' \
  --header "Authorization: Bearer $APICK_API_KEY" \
  --form 'image=@./profile.jpg'

```

- `data.result.length`가 1이면 통과, 0이면 얼굴 없음, 2 이상이면 여러 명입니다.

- `data.result[0].det_score`가 낮으면 얼굴이 흐릿한 사진일 수 있습니다.

## 사용 예시 2. 확실한 얼굴만 찾기

얼굴이 아닌 물체가 잡히면 기준 점수를 높입니다.

```bash

curl --fail-with-body --request POST 'https://apick.app/rest/face_detection' \
  --header "Authorization: Bearer $APICK_API_KEY" \
  --form 'image=@./crowd.jpg' \
  --form-string 'threshold=0.7'

```

- `data.result[].face_crop`의 두 좌표로 얼굴 영역을 잘라 쓸 수 있습니다.

- `threshold`는 0~0.9 범위입니다.

## 사용 예시 3. 얼굴 특징 정보 함께 받기

얼굴마다 특징 정보가 필요하면 `use_feature=1`을 보냅니다.

```bash

curl --fail-with-body --request POST 'https://apick.app/rest/face_detection' \
  --header "Authorization: Bearer $APICK_API_KEY" \
  --form 'image=@./profile.jpg' \
  --form-string 'use_feature=1'

```

- 각 얼굴 항목에 특징 정보가 추가로 담깁니다. 위치는 `face_crop`, 기준점은 `landmark`로 확인합니다.

## 코드·오류

### 업무 실패 응답

입력 오류·대상 없음·일시 실패는 data.error(사유)와 data.success=0으로 오며 api.cost는 0(과금 없음)입니다. HTTP 상태는 400·404·408·424 중 하나입니다. 입력 오류는 값을 고쳐 다시 요청하고, 408·424는 잠시 후 한 번 다시 시도하세요.

```json

{
  "data": {
    "error": "입력값을 확인해 주세요.",
    "success": 0
  },
  "api": {
    "success": true,
    "cost": 0,
    "ms": 5
  }
}

```

## 상세 기능·요금

업로드 용량 제한: 50MB multipart/form-data 요청에 포함된 첨부 이미지 합계는 최대 50MB입니다. 제한을 초과하면 HTTP 413과 REQUEST_TOO_LARGE 오류가 반환되며 과금되지 않습니다. 이용 전 확인 프로필 사진에 얼굴이 한 명만 있는지 검사하거나, 얼굴 위치에 맞춰 사진을 자르거나, 얼굴 영역에 직접 효과를 넣을 때 사용합니다. PNG·JPEG·WEBP·BMP 이미지를 받습니다. 얼굴을 가린 이미지 자체가 필요하면 얼굴 모자이크 처리를 쓰세요. 좌표는 원본 이미지의 왼쪽 위를 (0, 0)으로 하는 픽셀 값이며 소수점이 붙어 옵니다. 얼굴이 없으면 data.result는 빈 배열입니다. threshold는 얼굴로 인정할 기준 점수입니다. 값이 클수록 확실한 얼굴만 남고, 작을수록 흐릿하거나 작은 얼굴까지 찾습니다. 성공한 건당 3P입니다. 실패·시간 초과 응답은 과금되지 않습니다.

## 상세 요청

항목설정 메서드·주소POST https://apick.app/rest/face_detection 인증 헤더Authorization: Bearer 내 계정의 API 인증키 본문 형식multipart/form-data 요청 예시 form-data 전체 예제 보기

## 상세 응답

필드타입설명 dataobject인식 결과 resultarray찾은 얼굴 목록입니다. 얼굴이 없으면 빈 배열입니다. {}object얼굴 하나 face_croparray얼굴 사각형의 [[왼쪽 위 x, y], [오른쪽 아래 x, y]] 좌표입니다. 사진을 얼굴 기준으로 자를 때 씁니다. landmarkarray얼굴 기준점 5개의 [x, y] 좌표입니다. 순서는 왼쪽 눈, 오른쪽 눈, 코, 왼쪽 입꼬리, 오른쪽 입꼬리입니다. det_scorenumber얼굴일 가능성 0~1. 1에 가까울수록 확실한 얼굴입니다. widthinteger원본 이미지의 너비(픽셀)입니다. heightinteger원본 이미지의 높이(픽셀)입니다. successinteger처리 결과입니다. 1: 성공(과금), 0: 실패, 3: 시간 초과(과금 없음). apiobject호출 공통 정보 successboolean요청을 정상 처리했는지 여부입니다. costinteger이번 요청에서 차감된 포인트입니다. msinteger처리 시간(밀리초)입니다. pl_idinteger결제 기록 번호입니다. 문의할 때 함께 알려 주세요. 응답 예시 { "data": { "result": [ { "landmark": [ [429.3706970214844, 280.9442138671875], [458.5393371582031, 280.26409912109375], [443.2686462402344, 295.4951171875], [433.3480224609375, 311.8315124511719], [455.7586669921875, 311.30450439453125] ], "height": 472, "width": 742, "det_score": 0.8643505573272705, "face_crop": [ [424.3706970214844, 275.26409912109375], [463.5393371582031, 316.8315124511719] ] } ], "success": 1 }, "api": { "success": true, "cost": 3, "ms": 475, "pl_id": 108609 } } 얼굴 수는 data.result.length로 셉니다. 증명사진처럼 한 명만 있어야 하는 경우 길이가 1인지 확인하세요.

## 상세 코드·정책

오류와 대처 실패하면 data.error에 문구가 담기고 api.cost는 0입니다. HTTPdata.error대처 400필수 입력값이 없습니다.threshold를 0~0.9 사이 숫자로 보내세요. 400파일 유형이 맞지 않습니다. 이미지 형식의 파일만 허용됩니다.이미지 파일인지 확인하세요. 424첨부파일이 없습니다.파일 필드 이름을 image로 보냈는지 확인하세요. 424알 수 없는 이유로 실패했습니다.이미지를 JPEG 또는 PNG로 다시 저장해 한 번 더 요청하세요. 408처리 시간 초과로 실패했습니다.data.success가 3입니다. 이미지 해상도를 줄여 다시 요청하세요.

## 상세 예제

결과 예시 [이미지] [동영상] 호출 예시 같은 요청을 JavaScript와 Python으로 옮긴 예시입니다. 키는 환경변수 APICK_API_KEY 에서 읽습니다. JavaScript 예시 form-data 전체 예제 보기 Python 예시 form-data 전체 예제 보기
