FaceMatch REST API

API 문서

별도 SDK 없이 표준 HTTP 한 번 호출로 기존 앱·키오스크·출입장치에 얼굴인증을 붙입니다. 모든 요청은 multipart/form-data로 이미지를 전송하며, 회사코드 헤더 한 줄로 회사별 데이터가 완전히 분리됩니다.

Base URL
https://facematch.team1985.com
Content-Type
multipart/form-data
Authentication

인증 · 회사코드

모든 엔드포인트는 발급받은 회사코드(License Key)를 요구합니다. X-License-Key 헤더로 전달하는 것을 권장하며, 폼 필드 license_key로도 받습니다.

요청 헤더
X-License-Key: <회사코드>
회사코드는 관리자 콘솔에서 회사 등록 시 자동 발급됩니다. 같은 회사코드로 등록·인식된 데이터끼리만 매칭되며, 다른 회사의 데이터에는 접근할 수 없습니다.
Errors

에러 응답

실패 시 status 필드가 "error" 또는 "warning"으로 내려갑니다. 회사코드 관련 오류는 HTTP 상태코드로도 구분됩니다.

코드status의미
200success정상 처리 (인식 성공 여부는 recognized 필드로 구분)
200warning얼굴 미감지·전경 얼굴 없음 등 — 요청은 정상이나 처리할 얼굴이 없음
400error이미지를 읽을 수 없음 (손상·미지원 형식)
401error회사코드(license_key) 누락
403error유효하지 않은 회사코드 · 라이선스 유효기간 만료
Concepts

식별키 · 부가정보

FaceMatch는 평문 개인정보를 보관하지 않는 PII-free 구조입니다. 회원은 파트너가 정한 키로 식별하고, 이름·연락처 등은 암호화된 부가정보로만 저장됩니다.

개념설명
unique_key파트너 시스템의 회원 식별자(실질 유일키). 회원번호·ID 등 아무 값이나 사용. 매칭 성공 시 이 값이 그대로 반환되므로 자체 DB 조회 키로 씁니다.
group_key회사 하위의 그룹 구분값(지점·반 등, 선택). 등록 시 지정하면 탐지 시 group_key로 해당 그룹 소속만 후보로 좁힐 수 있습니다. 재등록(갱신) 판정 범위 = (회사, group_key, unique_key).
extra자유 형식 부가정보 JSON(이름·연락처 등). AES-256-GCM 으로 암호화 저장되고 매칭 성공 시 복호화되어 그대로 반환됩니다 — 자체 서버가 없는 고객사도 매칭 결과만으로 회원정보를 회수할 수 있습니다.

POST 얼굴등록 · 멀티임베딩

얼굴 이미지 1~N장에서 512차원 특징을 추출해 저장합니다. 정면·좌우·상하 등 여러 방향을 함께 등록하면 인식률이 크게 올라갑니다(권장 5장: 정면+네 모서리). 같은 (회사, group_key, unique_key)가 이미 있으면 갱신(update)됩니다.

POST/api/register

요청 파라미터 · multipart/form-data

필드타입설명
files 필수file[]얼굴 이미지 1~N장 (jpg/png). 같은 이름 files 필드를 반복 전송
unique_key 필수string파트너 회원 식별키. 중복 시 기존 등록을 갱신
poses 선택string이미지 순서와 1:1인 콤마구분 방향 라벨. 예: frontal,left_up,right_up,left_down,right_down
group_key 선택string그룹 구분값(지점·반 등). 탐지 시 같은 값으로 후보를 좁힐 수 있음
extra 선택JSON string부가정보 JSON 객체. 암호화 저장 후 매칭 시 복호화 반환. 예: {"name":"홍길동","grade":"A"}
license_key 선택string회사코드 (헤더 X-License-Key 미사용 시)
요청 예시 · 5방향 등록
curl -X POST https://facematch.team1985.com/api/register \
  -H "X-License-Key: <회사코드>" \
  -F files=@front.jpg -F files=@lu.jpg -F files=@ru.jpg \
  -F files=@ld.jpg -F files=@rd.jpg \
  -F poses=frontal,left_up,right_up,left_down,right_down \
  -F unique_key=member-1024 \
  -F group_key=A \
  -F extra='{"name":"홍길동","mobile":"01012345678"}'
응답 200
{
  "status": "success",
  "action": "inserted",   // 또는 "updated"
  "face_id": 12,
  "unique_key": "member-1024",
  "group_key": "A",
  "received": 5,   // 받은 이미지 수
  "accepted": 5,   // 품질게이트 통과·저장 수
  "poses": ["frontal","left_up","right_up","left_down","right_down"],
  "face": {
    "bbox": [142,88,320,300],
    "det_score": 0.99
  }
}
모든 프레임에서 얼굴을 감지하지 못하면 { "status": "warning", "message": "얼굴을 감지하지 못했습니다." } 가 반환됩니다. 일부만 실패하면 통과한 장수만 accepted에 반영됩니다.

POST 얼굴탐지 · 출석체크 1:N

이미지 1장에서 가장 가까운 전경 얼굴 1명만 골라 등록자와 1:N 매칭합니다. 여러 명이 줄 서 있어도 본인 1명만 인식해 출입·출석에 적합합니다.

POST/api/detect

요청 파라미터 · multipart/form-data

필드타입설명
file 필수file인식할 이미지
group_key 선택string지정 시 해당 그룹에 등록된 얼굴만 후보로 매칭
threshold 선택float매칭 임계값. 미지정 시 회사 설정 → 전역 기본(0.35) 순으로 적용
margin 선택float1·2위 유사도 차이 최소값(오인식 방지). 미지정 시 회사 설정 → 전역 기본(0.05)
min_face_ratio 선택float전경 얼굴로 인정할 최소 크기 비율 (기본 0.10)
license_key 선택string회사코드 (헤더 미사용 시)
요청 예시
curl -X POST https://facematch.team1985.com/api/detect \
  -H "X-License-Key: <회사코드>" \
  -F file=@photo.jpg \
  -F group_key=A
응답 200
{
  "status": "success",
  "recognized": true,
  "similarity": 0.987,   // 1위 유사도
  "similarity2": 0.141,  // 2위 유사도
  "gap": 0.846,          // 1-2위 차이
  "ambiguous": false,    // 닮은 사람과 구분 애매 여부
  "verified_by": null,      // 2차 모델(buffalo_l)로 확정 시 모델명, 아니면 null
  "threshold": 0.35,
  "margin": 0.05,
  "elapsed_ms": 176,
  "person": {
    "id": 12,
    "unique_key": "member-1024",
    "group_key": "A",
    "extra": { "name": "홍길동", "mobile": "01012345678" }
  },
  "num_faces_in_frame": 1
}
recognized: false여도 statussuccess입니다 — 인식 여부는 항상 recognized 필드로 판단하세요. 1·2위 유사도 차이가 margin보다 작으면 ambiguous: true와 함께 인식이 보류됩니다(재촬영 유도 권장). 응답에는 선택된 얼굴 좌표(selected)와 프레임 내 전체 얼굴(all_faces)도 포함됩니다.

멀티모델 2차검증 & 후보 반환

내부적으로 1차 모델이 애매(ambiguous)로 판정한 건은 변별력이 더 높은 2차 모델(buffalo_l)로 자동 재검증합니다. 2차가 확정하면 recognized: true + verified_by: "buffalo_l"로 응답합니다(앱은 그대로 두어도 됩니다 — 필드만 추가). 일란성 쌍둥이처럼 얼굴만으로 자동 확정이 불가한 경우에는 recognizedfalse로 두되, 아래처럼 후보 명단(candidates)을 함께 내려줍니다. 도입사에서 이 후보로 최종 선택 UI(둘 중 택1 등)를 구성할 수 있습니다.

애매 판정 시 응답 (후보 반환)
{
  "status": "success",
  "recognized": false,   // 자동 확정 안 함
  "ambiguous": true,
  "verified_by": null,
  "gap": 0.012,
  "message": "닮은 사람과 구분이 어렵습니다. 한 번 더 촬영해 주세요.",
  "candidates": [       // '이 중 하나' 후보(top-2)
    { "unique_key": "member-1024", "group_key": "A",
      "extra": { "name": "홍길동" }, "similarity": 0.712 },
    { "unique_key": "member-1025", "group_key": "A",
      "extra": { "name": "홍길순" }, "similarity": 0.700 }
  ]
}
활용 가이드
  • candidatesambiguous: true일 때만 포함됩니다.
  • 각 후보 형태는 person과 동일 + similarity(유사도) 추가.
  • recognized는 여전히 false — 서버는 자동 확정하지 않습니다.
  • 후보로 최종 선택 UI를 만들지, 재촬영을 유도할지는 도입사 정책입니다.
  • 기존 앱은 모르는 필드를 무시하므로 하위호환됩니다.

POST 다중탐지 · N:N

이미지 속 모든 얼굴을 탐지해 각자 1:N 매칭합니다. CCTV·단체 프레임에서 "지금 화면에 누가 보이는지" 명단을 한 번에 받습니다.

POST/api/multi-detect

요청 파라미터 · multipart/form-data

필드타입설명
file 필수file탐지할 이미지
group_key 선택string지정 시 해당 그룹에 등록된 얼굴만 후보로 매칭
threshold 선택float매칭 임계값. 미지정 시 회사 설정 → 전역 기본(0.35)
license_key 선택string회사코드 (헤더 미사용 시)
요청 예시
curl -X POST https://facematch.team1985.com/api/multi-detect \
  -H "X-License-Key: <회사코드>" \
  -F file=@crowd.jpg
응답 200
{
  "status": "success",
  "num_faces": 3,
  "recognized_count": 2,
  "elapsed_ms": 880,
  "faces": [
    {
      "recognized": true,
      "similarity": 0.987,
      "person": {
        "unique_key": "member-1024",
        "extra": { "name": "홍길동" }
      },
      "bbox": [88,60,240,250]
    },
    {
      "recognized": false,
      "similarity": 0.21,
      "person": null,
      "bbox": [410,90,560,270]
    }
  ]
}

GET 등록 목록

자기 회사에 등록된 얼굴 전체 목록입니다. 부가정보는 복호화되어 내려가고, name/mobile은 부가정보에서 병합된 값입니다.

GET/api/faces
요청 예시
curl https://facematch.team1985.com/api/faces \
  -H "X-License-Key: <회사코드>"
응답 200
{
  "status": "success",
  "list": [
    {
      "id": 12,
      "unique_key": "member-1024",
      "group_key": "A",
      "extra": { "name": "홍길동", "mobile": "01012345678" },
      "name": "홍길동",
      "mobile": "01012345678",
      "image_path": "/images/reg_....jpg",
      "created_at": 1782301234
    }
  ]
}

GET 등록 상세 · 방향별 이미지

등록 얼굴 1건의 방향별 등록 이미지와 복호화된 부가정보를 조회합니다.

GET/api/faces/{face_id}/poses
요청 예시
curl https://facematch.team1985.com/api/faces/12/poses \
  -H "X-License-Key: <회사코드>"
응답 200
{
  "status": "success",
  "unique_key": "member-1024",
  "group_key": "A",
  "extra": { "name": "홍길동" },
  "list": [
    { "pose": "frontal", "image_path": "/images/...", "quality": 312.5 },
    { "pose": "left_up", "image_path": "/images/...", "quality": 287.1 }
  ]
}

POST 등록 수정

이름·연락처를 수정합니다. 값은 암호화된 부가정보에 병합 저장되며, 임베딩·사진은 유지됩니다.

POST/api/faces/{face_id}
필드타입설명
name 선택string이름. 빈 값이면 부가정보에서 제거
mobile 선택string연락처. 빈 값이면 부가정보에서 제거
요청 예시
curl -X POST https://facematch.team1985.com/api/faces/12 \
  -H "X-License-Key: <회사코드>" \
  -F name=홍길동 -F mobile=01012345678

DELETE 등록 삭제

등록 얼굴을 삭제합니다. 삭제 즉시 인식 대상에서 제외되며, 과거 매칭 로그의 증적 이미지는 보존됩니다(소프트 삭제). 등록 시 사용한 unique_key(식별키)로 삭제하는 것이 기본이며, 내부 face_id를 아는 경우 ID 삭제도 가능합니다.

DELETE/api/faces/by-key/{unique_key}
요청 예시 — 식별키로 삭제 (권장)
curl -X DELETE "https://facematch.team1985.com/api/faces/by-key/member-1024?group_key=gangnam" \
  -H "X-License-Key: <회사코드>"

# 응답
{ "status": "success", "deleted": 1, "face_ids": [12] }
group_key옵션입니다 — 전달하면 해당 그룹 스코프의 등록만 삭제하고, 생략하면 회사 내 해당 식별키의 등록을 모두 삭제합니다(응답의 deleted가 삭제 건수). 일치하는 등록이 없으면 404를 반환합니다.
DELETE/api/faces/{face_id}
요청 예시 — 내부 ID로 삭제
curl -X DELETE https://facematch.team1985.com/api/faces/12 \
  -H "X-License-Key: <회사코드>"

GET 매칭 로그

최근 인식 시도 이력입니다. 어떤 방향(matched_pose) 등록 이미지가 매칭을 이겼는지, 시도 사진(probe_image)과 매칭된 등록 사진(matched_image)까지 증적으로 제공됩니다.

GET/api/logs?limit=100
요청 예시
curl "https://facematch.team1985.com/api/logs?limit=50" \
  -H "X-License-Key: <회사코드>"
응답 200
{
  "status": "success",
  "list": [
    {
      "id": 224,
      "mode": "detect",   // detect | multi
      "recognized": true,
      "name": "홍길동",
      "unique_key": "member-1024",
      "group_key": "A",
      "similarity": 0.723,
      "threshold": 0.35,
      "matched_pose": "left_up",
      "probe_image": "/images/probe_....jpg",
      "matched_image": "/images/reg_....jpg",
      "elapsed_ms": 180,
      "num_faces": 1,
      "created_at": 1782301234
    }
  ]
}
FaceMatch · 얼굴인식 본인인증 플랫폼  ·  OpenAPI 명세 · 연동 가이드 · SDK
https://facematch.team1985.com · © 2026 team1985