# 여권 개인정보 마스킹



여권의 지정 정보를 추출하고 여권번호 및 MRZ 영역을 마스킹합니다.



인증: Authorization: Bearer $APICK_API_KEY

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

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



## POST /rest/identity_document_passport 응답 필드

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

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

- `data.result.document_type` (string): 판독한 문서의 종류입니다. 예: id_card(주민등록증), passport(여권), residence_card(외국인등록증). 요청한 문서와 같은지 먼저 확인하세요.

- `data.result.fields` (object): 문서에서 추출한 항목별 값 묶음입니다. 문서 종류마다 키가 다르며, 읽지 못한 항목은 빈 문자열이거나 생략됩니다.

- `data.result.fields.country_code` (string): 발행국 코드(영문 3자리)입니다. 예: KOR 문자열로 오며, 값이 없으면 빈 문자열이거나 필드가 생략됩니다. 같은 응답의 다른 필드와 함께 해석하세요.

- `data.result.fields.surname` (string): 여권의 성(Surname)입니다. 영문 표기 그대로 오며, 복합 성은 공백으로 구분될 수 있습니다.

- `data.result.fields.given_names` (string): 여권의 이름(Given names)입니다. 영문 표기 그대로 오며, 여러 이름은 공백으로 구분됩니다.

- `data.result.fields.korean_name` (string): 여권에 함께 표기된 한글 성명입니다. 영문 이름과 대조해 동일 인물인지 확인하세요.

- `data.result.fields.date_of_birth` (string): 여권에 표기된 생년월일(YYYYMMDD)입니다. 주민등록번호의 생년월일과 다를 수 있습니다.

- `data.result.fields.sex` (string): 여권에 표기된 성별 코드입니다. M(남), F(여), X(미상) 중 하나로 옵니다.

- `data.result.fields.nationality` (string): 여권에 표기된 국적입니다. 국가명 또는 ISO 코드로 오며, 문서 판독 상태에 따라 표기가 달라질 수 있습니다.

- `data.result.masked_image` (string): 개인정보를 가린 뒤 만든 이미지의 Base64 데이터입니다. data URI 접두어 없이 순수 Base64만 오므로 image/png로 디코딩해 저장하세요.

- `data.result.image_mime` (string): 마스킹 이미지의 MIME 형식입니다. 현재 image/png로 고정되어 있으며, 저장 파일 확장자와 맞춰야 합니다.

- `data.result.elapsed_ms` (integer): OCR·항목 추출·마스킹을 마치는 데 걸린 서버 처리 시간(밀리초)입니다. 네트워크 전송 시간은 포함되지 않습니다.

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

- `data.error` (string): 오류 원인을 설명하는 문구입니다. 성공 응답에는 없거나 빈 문자열입니다.

- `data.error_code` (string): 실패 원인 코드입니다. 아래 오류 표의 코드로 분기하세요. 성공 응답에는 없습니다.

- `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/identity_document_passport



### 입력

- `image` (file, 필수): 여권 인적사항면 이미지 하나입니다. 맨 아래 두 줄 코드(MRZ)가 잘리지 않게 촬영해야 합니다. PNG 또는 JPEG만 받으며 50MB 이하입니다.



### 응답 명세

```json

{
  "type": "object",
  "properties": {
    "data": {
      "type": "object",
      "properties": {
        "result": {
          "type": "object",
          "properties": {
            "document_type": {
              "type": "string",
              "description": "문서 종류입니다. 이 API는 항상 passport입니다."
            },
            "fields": {
              "type": "object",
              "properties": {
                "country_code": {
                  "type": "string",
                  "description": "발행국 코드(영문 3자리)입니다. 예: KOR"
                },
                "surname": {
                  "type": "string",
                  "description": "영문 성입니다. 예: HONG"
                },
                "given_names": {
                  "type": "string",
                  "description": "영문 이름입니다. 예: GILDONG"
                },
                "korean_name": {
                  "type": "string",
                  "description": "여권에 적힌 한글 성명입니다. 예: 홍길동"
                },
                "date_of_birth": {
                  "type": "string",
                  "description": "생년월일입니다. 숫자 8자리(YYYYMMDD)입니다. 예: 19900101"
                },
                "sex": {
                  "type": "string",
                  "description": "성별입니다. M, F, X 중 하나입니다."
                },
                "nationality": {
                  "type": "string",
                  "description": "여권에 적힌 국적입니다. 예: REPUBLIC OF KOREA"
                }
              },
              "description": "이미지에서 읽은 항목입니다. 성공 응답에서는 아래 일곱 항목이 모두 채워져 있습니다."
            },
            "masked_image": {
              "type": "string",
              "description": "여권번호와 맨 아래 두 줄 코드를 가린 PNG 이미지의 Base64 문자열입니다. 디코딩해 .png 파일로 저장하세요."
            },
            "image_mime": {
              "type": "string",
              "description": "masked_image의 형식입니다. 항상 image/png입니다."
            },
            "elapsed_ms": {
              "type": "integer",
              "description": "항목 인식과 가림 처리에 걸린 시간(밀리초)입니다. 네트워크 전송 시간은 포함되지 않습니다."
            }
          },
          "description": "읽은 항목과 가린 이미지입니다. 실패 응답에는 없습니다."
        },
        "success": {
          "type": "integer",
          "description": "처리 상태입니다. 1이면 성공(요금 차감), 0이면 실패(차감 없음)입니다."
        },
        "error": {
          "type": "string",
          "description": "실패 사유 문구입니다. 성공 응답에는 없습니다."
        },
        "error_code": {
          "type": "string",
          "description": "실패 원인 코드입니다. 아래 오류 표의 코드로 분기하세요. 성공 응답에는 없습니다."
        }
      },
      "description": "처리 결과 묶음입니다. 성공하면 result가, 실패하면 error·error_code가 들어 있습니다."
    },
    "api": {
      "type": "object",
      "properties": {
        "success": {
          "type": "boolean",
          "description": "요청을 정상적으로 받아 처리했는지 여부입니다. 인식 성공 여부는 data.success로 확인하세요."
        },
        "cost": {
          "type": "integer",
          "description": "이번 호출에서 차감된 포인트입니다. 실패 응답은 0입니다."
        },
        "ms": {
          "type": "integer",
          "description": "요청을 받아 응답을 만들기까지 걸린 시간(밀리초)입니다. 네트워크 왕복 시간은 포함되지 않습니다."
        },
        "pl_id": {
          "type": "integer",
          "description": "포인트 차감 기록 번호입니다. 차감이 있었던 호출에만 값이 있으며 과금 문의 때 사용합니다."
        }
      },
      "description": "호출 공통 정보입니다. 처리 여부·차감 포인트·처리 시간·차감 기록 번호가 들어 있습니다."
    }
  }
}

```

### 정적 응답 예시

```json

{
  "data": {
    "result": {
      "document_type": "passport",
      "fields": {
        "country_code": "KOR",
        "surname": "HONG",
        "given_names": "GILDONG",
        "korean_name": "홍길동",
        "date_of_birth": "19900101",
        "sex": "M",
        "nationality": "REPUBLIC OF KOREA"
      },
      "masked_image": "iVBORw0KGgoAAAANSUhEUgAA...(생략)",
      "image_mime": "image/png",
      "elapsed_ms": 458
    },
    "success": 1
  },
  "api": {
    "success": true,
    "cost": 30,
    "ms": 610,
    "pl_id": 1595642
  }
}

```

### curl

```curl

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

```

### Node.js (서버 ESM)

```javascript

import { readFile } from "node:fs/promises";
const form = new FormData();
form.append("image", new Blob([await readFile("./passport.jpg")]), "passport.jpg");
const response = await fetch("https://apick.app/rest/identity_document_passport", {
  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", ("passport.jpg", open("./passport.jpg", "rb"))),
]
response = requests.request("POST", "https://apick.app/rest/identity_document_passport",
    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('./passport.jpg'),
];
$curl = curl_init('https://apick.app/rest/identity_document_passport');
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/identity_document_passport' \
  --header "Authorization: Bearer $APICK_API_KEY" \
  --form 'image=@./passport.jpg'

```

- `data.result.fields.surname`·`given_names`를 예약 시스템의 영문 성명으로 씁니다.

- 응답에는 여권번호가 없으므로 여권번호가 필요하면 고객에게 따로 입력받습니다.

## 사용 예시 2. 하단 코드가 잘린 사진

맨 아래 두 줄 코드가 잘린 사진을 보낸 경우의 처리입니다.

```bash

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

```

- `data.error_code`가 `IDENTITY_TEXT_UNREADABLE`(HTTP 422)이면 하단 두 줄이 모두 보이도록 다시 촬영을 요청합니다.

## 코드·오류

- OCR_IMAGE_MISSING (400): 이미지 파일을 첨부하세요.

- OCR_UNSUPPORTED_IMAGE (400): 지원하는 이미지 형식을 사용하세요.

- OCR_IMAGE_TOO_LARGE (413): 서비스의 파일 크기 제한을 확인하세요.

- IDENTITY_TEXT_UNREADABLE (422): 판독할 수 있는 문서 이미지를 첨부하세요.

- IDENTITY_DOCUMENT_MISMATCH (400): 요청한 종류와 일치하는 문서를 첨부하세요.

- IDENTITY_PROCESSING_FAILED (424): 문서 처리에 실패했습니다. 다시 시도하거나 문의하세요.

## 상세 기능·요금

업로드 용량 제한: 50MB 첨부 이미지는 최대 50MB이며 PNG 또는 JPEG 형식만 지원합니다. 제한을 초과하면 HTTP 413과 REQUEST_TOO_LARGE 오류가 반환되며 과금되지 않습니다. 제공 정보 여권 인적사항면(사진이 있는 면) 이미지 하나를 보내면, 한 번의 호출로 발행국·영문 성/이름·한글 성명·생년월일·성별·국적을 읽어 주고, 여권번호와 맨 아래 두 줄 코드(MRZ)를 가린 PNG 이미지(Base64)를 함께 돌려줍니다. 여권 사본을 여권번호를 가린 채 보관해야 하는 예약·가입·계약 절차에서 사용합니다. 응답에는 여권번호가 들어 있지 않습니다. 필요한 항목을 모두 읽고 가릴 위치까지 확정해야 성공합니다. 하나라도 확정하지 못하면 가린 이미지와 일부 값도 돌려주지 않고 실패하며, 요금이 차감되지 않습니다. 정보주체의 동의 등 적법한 처리 근거가 있을 때만 호출하세요. Method URL POST https://apick.app/rest/identity_document_passport

## 상세 요청

Header 이름 필수 설명 Authorization 필수 Bearer 인증키. 예: Authorization: Bearer 발급받은_API_키 맨 아래 두 줄 코드가 없거나 흐리면 실패합니다. 면 전체가 화면에 들어오고 빛 반사가 없도록 촬영하세요.

## 상세 응답

Body 필드 타입 설명 data Object 처리 결과 묶음입니다. 성공하면 result가, 실패하면 error·error_code가 들어 있습니다. result Object 읽은 항목과 가린 이미지입니다. 실패 응답에는 없습니다. document_type String 문서 종류입니다. 이 API는 항상 passport입니다. fields Object 이미지에서 읽은 항목입니다. 성공 응답에서는 아래 일곱 항목이 모두 채워져 있습니다. country_code String 발행국 코드(영문 3자리)입니다. 예: KOR surname String 영문 성입니다. 예: HONG given_names String 영문 이름입니다. 예: GILDONG korean_name String 여권에 적힌 한글 성명입니다. 예: 홍길동 date_of_birth String 생년월일입니다. 숫자 8자리(YYYYMMDD)입니다. 예: 19900101 sex String 성별입니다. M, F, X 중 하나입니다. nationality String 여권에 적힌 국적입니다. 예: REPUBLIC OF KOREA masked_image String 여권번호와 맨 아래 두 줄 코드를 가린 PNG 이미지의 Base64 문자열입니다. 디코딩해 .png 파일로 저장하세요. image_mime String masked_image의 형식입니다. 항상 image/png입니다. elapsed_ms Integer 항목 인식과 가림 처리에 걸린 시간(밀리초)입니다. 네트워크 전송 시간은 포함되지 않습니다. error String 실패 사유 문구입니다. 성공 응답에는 없습니다. error_code String 실패 원인 코드입니다. 아래 오류 표의 코드로 분기하세요. 성공 응답에는 없습니다. success Integer 처리 상태입니다. 1이면 성공(요금 차감), 0이면 실패(차감 없음)입니다. api Object 호출 공통 정보입니다. 처리 여부·차감 포인트·처리 시간·차감 기록 번호가 들어 있습니다. success Boolean 요청을 정상적으로 받아 처리했는지 여부입니다. 인식 성공 여부는 data.success로 확인하세요. cost Integer 이번 호출에서 차감된 포인트입니다. 실패 응답은 0입니다. ms Integer 요청을 받아 응답을 만들기까지 걸린 시간(밀리초)입니다. 네트워크 왕복 시간은 포함되지 않습니다. pl_id Integer 포인트 차감 기록 번호입니다. 차감이 있었던 호출에만 값이 있으며 과금 문의 때 사용합니다. 응답 예시 { "data": { "result": { "document_type": "passport", "fields": { "country_code": "KOR", "surname": "HONG", "given_names": "GILDONG", "korean_name": "홍길동", "date_of_birth": "19900101", "sex": "M", "nationality": "REPUBLIC OF KOREA" }, "masked_image": "iVBORw0KGgoAAAANSUhEUgAA...(생략)", "image_mime": "image/png", "elapsed_ms": 458 }, "success": 1 }, "api": { "success": true, "cost": 30, "ms": 610, "pl_id": 1595642 } }

## 상세 코드·정책

입력 오류 HTTP / 오류 코드 data.error 조치 400OCR_IMAGE_MISSING 첨부파일이 없습니다. image 항목에 파일 하나를 multipart/form-data로 첨부하세요. 400OCR_UNSUPPORTED_IMAGE PNG 또는 JPEG 이미지 파일만 허용됩니다. PNG·JPEG로 바꿔 다시 보내세요. 손상된 파일이면 "지원되지 않거나 손상된 이미지입니다."가 옵니다. 413OCR_IMAGE_TOO_LARGE 이미지 파일은 50MB 이하여야 합니다. 해상도를 줄이거나 JPEG로 압축해 50MB 이하로 보내세요. 오류 응답 실패 응답은 data.success: 0, api.cost: 0을 유지하며 data.error_code로 원인을 구분합니다. HTTP / 오류 코드설명 422IDENTITY_TEXT_UNREADABLE 글자가 일부 가려졌거나 선명하지 않아 필요한 정보를 정확히 인식할 수 없습니다. 문서 전체와 글자가 선명하게 보이는 이미지를 업로드해 주세요. 400IDENTITY_DOCUMENT_MISMATCH 요청한 신분증 종류와 이미지가 일치하지 않습니다. 올바른 신분증 이미지를 업로드해 주세요. 424IDENTITY_PROCESSING_FAILED 이미지 처리 중 오류가 발생했습니다. 잠시 후 다시 시도해 주세요.

## 상세 예제

요청 예시 form-data 전체 예제 보기 마스킹 이미지 저장 (Python) form-data 전체 예제 보기
