{
  "openapi" : "3.1.0",
  "info" : {
    "title" : "headless Open API",
    "description" : "대한민국 은행·홈택스·법인카드 데이터를 표준 스키마와 REST 호출로 받는 외부 개발자용 API입니다.\n\n## 인증\n모든 요청에 API Key를 Bearer 토큰으로 함께 보낼 수 있습니다.\n\n```\nAuthorization: Bearer h6s_live_...\n```\n\nAPI Key 는 콘솔(https://h6s.ai/console/api-keys) 에서 발급할 수 있습니다.\n\n## 비동기 수집 — 3단계\n데이터 수집은 비동기로 처리됩니다. 다음 세 단계로 결과를 받아볼 수 있습니다.\n\n1. **수집 요청** — `POST /api/v1/data-jobs` 에 providerCode · schema · params 를 담아 요청합니다.\n   날짜 범위가 필요한 schema 는 `params.dateRangeStart` 와 `params.dateRangeEnd` 를 함께 보냅니다.\n   응답에는 작업 식별자 `id`, 현재 `kind` (`InProgress` / `Succeeded` / `Failed`),\n   그리고 폴링에 사용할 `suggestedPollIntervalMs` 와 `maxWaitSeconds` 가 포함됩니다.\n   진행중(`InProgress`)에는 `phase` (`PENDING` / `RUNNING`) 로 대기열/수집중을 구분합니다.\n2. **상태 폴링** — `GET /api/v1/data-jobs/{id}` 로 작업 상태를 확인합니다.\n   응답에 포함된 `suggestedPollIntervalMs` (기본 5,000ms) 주기로 폴링하고,\n   `kind` 가 `Succeeded` 또는 `Failed` 가 되면 폴링을 종료합니다.\n   `maxWaitSeconds` 는 자동 재개까지 감안해 terminal 상태 도달을 기다릴 권장 상한입니다.\n   별도 timeout 정책이 없다면 클라이언트 polling budget 으로 사용합니다.\n3. **결과 조회** — JSON 은 `GET /api/v1/data-jobs/{id}/results`,\n   CSV 는 `GET /api/v1/data-jobs/{id}/results.csv` 로 받습니다.\n\n`kind` 가 `Failed` 인 경우 응답의 `error` 객체에 다음 세 필드가 함께 제공됩니다.\n- `error.code` — 오류 유형 식별자 (예: `LOGIN_FAILED`, `JOB_TIMEOUT`)\n- `error.message` — 사용자에게 그대로 노출할 수 있는 안내 문구. 다음 액션 안내까지 포함되어 있습니다.\n- `error.retryable` — `true` 면 동일 요청으로 안전하게 재시도할 수 있습니다.\n\n## Rate Limit\n- 분당 100, 시간당 5000 (per API Key). 초과하면 HTTP 429와 JSON `{\"code\":\"API_RATE_LIMITED\",...}` 가 반환됩니다.\n- 모든 응답에 `X-RateLimit-Limit-Minute`, `X-RateLimit-Limit-Hour`, `X-RateLimit-Remaining` 헤더가 포함됩니다.\n- 429 응답에는 `Retry-After` (초) 헤더가 함께 내려갑니다.\n\n## 에러 응답\n모든 에러는 일관된 셰이프로 반환됩니다.\n```json\n{\"code\": \"API_KEY_NOT_FOUND\", \"message\": \"API 키를 찾을 수 없습니다\", \"requestId\": \"...\"}\n```\n검증 실패의 경우 `fieldErrors` 배열이 함께 포함됩니다.\n\n## 사용 사례\n- **정기 적재 cron** — 매월 1일 자체 스케줄러에서 `POST /api/v1/data-jobs` 를 호출하고, `/results.csv` 결과를 자체 DB · 데이터 웨어하우스로 적재합니다.\n- **자체 어드민 · BI 에서 직접 호출** — 백오피스 화면의 \"갱신\" 액션이 곧 REST 호출입니다. 폴링이 진행되는 동안 진행률을 표시합니다.\n- **자격증명 변경 직후 검증** — 자격증명 등록·갱신 후 작은 범위 data-job 한 건으로 유효성을 확인하고, 응답의 `failureCategory == CREDENTIAL` 여부로 판정합니다.",
    "version" : "v1"
  },
  "servers" : [ {
    "url" : "https://api.h6s.ai",
    "description" : "Production"
  } ],
  "security" : [ {
    "ApiKeyBearer" : [ ]
  } ],
  "tags" : [ {
    "name" : "DataJob",
    "description" : "스크래핑 수집 요청 생성/조회"
  } ],
  "paths" : {
    "/api/v1/data-jobs" : {
      "get" : {
        "tags" : [ "DataJob" ],
        "summary" : "수집 요청 목록",
        "description" : "커서 페이지네이션. status / actionCodes 로 필터. cursor는 base64 인코딩된 불투명 문자열입니다. 직전 응답의 nextCursor를 그대로 전달하면 다음 페이지를 조회할 수 있습니다. limit 은 1~100 사이 정수, 미지정 시 기본 20.",
        "operationId" : "list_1",
        "parameters" : [ {
          "name" : "cursor",
          "in" : "query",
          "required" : false,
          "schema" : {
            "type" : "string"
          }
        }, {
          "name" : "limit",
          "in" : "query",
          "required" : false,
          "schema" : {
            "type" : "integer",
            "format" : "int32",
            "maximum" : 100,
            "minimum" : 1
          }
        }, {
          "name" : "status",
          "in" : "query",
          "required" : false,
          "schema" : {
            "type" : "string"
          }
        }, {
          "name" : "actionCodes",
          "in" : "query",
          "required" : false,
          "schema" : {
            "type" : "array",
            "items" : {
              "type" : "string"
            }
          }
        } ],
        "responses" : {
          "200" : {
            "description" : "OK",
            "content" : {
              "application/json" : {
                "schema" : {
                  "$ref" : "#/components/schemas/DataJobPageHttpResponse"
                }
              }
            }
          }
        }
      },
      "post" : {
        "tags" : [ "DataJob" ],
        "summary" : "수집 요청 생성",
        "description" : "providerCode + schema + params 로 수집을 시작합니다. params 필드는 선택한 schema 의 요청 필드이며, 전체 필드 정의와 응답 body 는 GET /api/v1/schemas/{schema} 응답에서 확인할 수 있습니다. 날짜 범위가 필요한 schema 는 dateRangeStart/dateRangeEnd 를 params 안에 넣습니다.",
        "operationId" : "create_1",
        "parameters" : [ {
          "name" : "Idempotency-Key",
          "in" : "header",
          "description" : "선택 헤더. 네트워크 오류 뒤 같은 수집 요청을 재시도할 때 같은 값을 보냅니다. 1-128자이며, 같은 값으로 요청 내용이 달라지면 409를 반환합니다.",
          "required" : false,
          "schema" : {
            "type" : "string"
          },
          "example" : "data-job-20260711-001"
        } ],
        "requestBody" : {
          "content" : {
            "application/json" : {
              "schema" : {
                "$ref" : "#/components/schemas/CreateDataJobHttpRequest"
              },
              "examples" : {
                "계좌 목록" : {
                  "description" : "계좌 목록",
                  "value" : {
                    "providerCode" : "CB_SHINHAN",
                    "schema" : "bank.accounts.cb.v1",
                    "params" : { }
                  }
                },
                "입출금내역" : {
                  "description" : "입출금내역",
                  "value" : {
                    "providerCode" : "CB_SHINHAN",
                    "schema" : "bank.transactions.cb.v1",
                    "params" : {
                      "dateRangeStart" : "2026-01-01",
                      "dateRangeEnd" : "2026-01-31",
                      "accountNumber" : [ "1234567890" ],
                      "currencyCode" : "KRW"
                    }
                  }
                },
                "법인카드 승인내역" : {
                  "description" : "법인카드 승인내역",
                  "value" : {
                    "providerCode" : "CCD_LOTTE",
                    "schema" : "card.approvals.corp.v1",
                    "params" : {
                      "dateRangeStart" : "2026-01-01",
                      "dateRangeEnd" : "2026-01-31",
                      "cardNumberMasked" : [ "5105*********227" ]
                    }
                  }
                }
              }
            }
          },
          "required" : true
        },
        "responses" : {
          "201" : {
            "description" : "Created",
            "content" : {
              "application/json" : {
                "schema" : {
                  "oneOf" : [ {
                    "$ref" : "#/components/schemas/Failed"
                  }, {
                    "$ref" : "#/components/schemas/InProgress"
                  }, {
                    "$ref" : "#/components/schemas/Succeeded"
                  } ]
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/data-jobs/{id}" : {
      "get" : {
        "tags" : [ "DataJob" ],
        "summary" : "수집 요청 상세",
        "description" : "수집 요청 진행 상태. 종료된 SUCCEEDED 잡은 `recordCount` 로 수집 레코드 수를 확인.",
        "operationId" : "get_6",
        "parameters" : [ {
          "name" : "id",
          "in" : "path",
          "required" : true,
          "schema" : {
            "type" : "string",
            "format" : "uuid"
          }
        } ],
        "responses" : {
          "200" : {
            "description" : "OK",
            "content" : {
              "application/json" : {
                "schema" : {
                  "oneOf" : [ {
                    "$ref" : "#/components/schemas/Failed"
                  }, {
                    "$ref" : "#/components/schemas/InProgress"
                  }, {
                    "$ref" : "#/components/schemas/Succeeded"
                  } ]
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/data-jobs/{id}/results" : {
      "get" : {
        "tags" : [ "DataJob" ],
        "summary" : "수집 요청 결과",
        "description" : "수집 요청의 데이터. schema 필드에 따라 data 아이템의 ContractRecord variant 가 결정됨. 진행중(InProgress)에도 처리가 끝난 단위의 데이터를 부분 결과로 반환하며, totalCount 는 현재까지 수집된 레코드 수입니다.",
        "operationId" : "getResults",
        "parameters" : [ {
          "name" : "id",
          "in" : "path",
          "required" : true,
          "schema" : {
            "type" : "string",
            "format" : "uuid"
          }
        } ],
        "responses" : {
          "200" : {
            "description" : "OK",
            "content" : {
              "application/json" : {
                "schema" : {
                  "$ref" : "#/components/schemas/DataJobResultsHttpResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/data-jobs/{id}/results.csv" : {
      "get" : {
        "tags" : [ "DataJob" ],
        "summary" : "수집 요청 결과 (CSV)",
        "description" : "수집 요청의 데이터를 CSV (UTF-8 + BOM) 로 다운로드한다. 진행중에는 처리가 끝난 단위의 부분 결과가 포함된다. 헤더는 `@ContractField.displayName` 한국어 라벨이며, Excel 한글 호환을 위해 BOM 이 포함된다.",
        "operationId" : "downloadResultsCsv",
        "parameters" : [ {
          "name" : "id",
          "in" : "path",
          "required" : true,
          "schema" : {
            "type" : "string",
            "format" : "uuid"
          }
        } ],
        "responses" : {
          "200" : {
            "description" : "OK",
            "content" : {
              "text/csv;charset=UTF-8" : {
                "schema" : {
                  "type" : "string",
                  "format" : "binary"
                }
              }
            }
          }
        }
      }
    }
  },
  "components" : {
    "schemas" : {
      "CreateDataJobHttpRequest" : {
        "type" : "object",
        "properties" : {
          "params" : {
            "type" : "object",
            "additionalProperties" : { },
            "description" : "선택한 schema 의 요청 파라미터. 필드 목록과 응답 body 는 https://h6s.ai/docs/api/schemas 에서 schemaId 별로 확인할 수 있습니다. 날짜 범위가 필요한 schema 는 dateRangeStart/dateRangeEnd 를 params 안에 넣습니다.",
            "example" : {
              "dateRangeStart" : "2026-01-01",
              "dateRangeEnd" : "2026-01-31"
            }
          },
          "providerCode" : {
            "type" : "string",
            "minLength" : 1
          },
          "schema" : {
            "type" : "string",
            "minLength" : 1
          }
        },
        "required" : [ "providerCode", "schema" ]
      },
      "DataJobHttpResponse" : {
        "type" : "object",
        "discriminator" : {
          "propertyName" : "kind",
          "mapping" : {
            "InProgress" : "#/components/schemas/InProgress",
            "Succeeded" : "#/components/schemas/Succeeded",
            "Failed" : "#/components/schemas/Failed"
          }
        },
        "properties" : {
          "id" : {
            "type" : "string",
            "format" : "uuid"
          },
          "kind" : {
            "type" : "string"
          },
          "maxWaitSeconds" : {
            "type" : "integer",
            "format" : "int64",
            "description" : "자동 재개까지 감안해 이 수집 요청이 종료 상태에 도달하기를 기다릴 권장 상한 (초). 클라이언트가 별도 timeout 을 정하지 않았다면 이 값을 polling budget 으로 사용할 수 있다.",
            "example" : 7230
          },
          "providerCode" : {
            "type" : "string"
          },
          "schema" : {
            "type" : "string"
          },
          "suggestedPollIntervalMs" : {
            "type" : "integer",
            "format" : "int64",
            "description" : "GET /data-jobs/{id} 를 폴링할 때 권장하는 간격 (ms). kind 가 InProgress 인 동안만 의미 있다.",
            "example" : 5000
          }
        },
        "required" : [ "id", "kind", "maxWaitSeconds", "providerCode", "schema", "suggestedPollIntervalMs" ]
      },
      "ErrorHttpField" : {
        "type" : "object",
        "properties" : {
          "category" : {
            "type" : "string",
            "description" : "알림·재시도·입력 검증 정책 분기를 위한 보편 카테고리. 오류 코드 카탈로그가 늘어나도 customer 가 자체 매핑을 만들 필요 없이 이 값만으로 분기할 수 있다. 실제 자동 재시도 결정의 단일 진실 원천은 응답의 `retryable` 필드다.\n\n- `CREDENTIAL` (retryable=false) — 자격증명 문제. 등록된 자격증명으로 기관 로그인·서명이 실패. 사용자가 자격증명을 고쳐야 풀린다 → 재등록·재인증 안내.\n- `USER_ENVIRONMENT` (retryable=false) — 사용자 환경 문제. 자격증명은 맞지만 사용자 측 환경이 차단(해외 IP 차단, 인증서가 해당 기관에 미등록 등) → 환경 점검 안내.\n- `INVALID_INPUT` (retryable=false) — 요청 매개변수·대상 부적합(작업과 안 맞는 계좌, 조회 불가 기간, 결과 0건) → 입력값 점검.\n- `CREDENTIAL_MISSING` (retryable=false) — credential lifecycle 문제. 참조한 credential 이 삭제·비활성 → 재바인딩 또는 재등록.\n- `TRANSIENT` (retryable=true) — 일시 장애(rate limit·timeout·중복 로그인·기관 점검/지연 등). 동일 요청 재시도 가능.\n- `OTHER` (retryable=false) — 보편 카테고리 미해당(플랜 한도 초과, 미분류 fallback, 미매핑 오류 코드 전부). 오류 코드와 오류 메시지로 개별 판단.",
            "enum" : [ "CREDENTIAL", "USER_ENVIRONMENT", "INVALID_INPUT", "CREDENTIAL_MISSING", "TRANSIENT", "OTHER" ]
          },
          "code" : {
            "type" : "string",
            "description" : "안정 식별자. 정규화된 `ScrapingErrorCode` enum 이름으로 세부 오류 처리에 사용한다. 매핑되지 않은 값은 `UNKNOWN` 으로 반환한다. 세부 분기가 필요 없으면 실패 카테고리로 분기하는 편이 단순하다.\n\n전체 카탈로그 (33개):\n\n`실패 카테고리=CREDENTIAL` (사용자 자격증명 조치 필요, retryable=false)\n- `LOGIN_FAILED` - 로그인 실패 (ID·비밀번호·인증서 부정확)\n- `LOGIN_CREDENTIALS_MISMATCH` - 로그인 정보(아이디·비밀번호·주민등록번호) 불일치\n- `LOGIN_SECOND_FACTOR_REQUIRED` - ID 로그인의 2차 인증번호(주민번호 앞 7자리) 미입력\n- `LOGIN_LOCKED` - 비밀번호 연속 입력 오류로 계정 잠김 (기관에서 비밀번호 재설정 필요)\n- `NO_VALID_CREDENTIAL` - 유효한 인증 정보 없음 (재등록 필요)\n- `CERT_INVALID` - 인증서 폐기·미등록·서명 실패 (갱신·재등록 필요)\n- `BUSINESS_NUMBER_MISMATCH` - 등록한 사업자등록번호가 계정 정보와 불일치 (예: 홈택스)\n\n`실패 카테고리=USER_ENVIRONMENT` (사용자 환경 점검 필요, retryable=false)\n- `OVERSEAS_IP_BLOCKED` - 기관의 해외 IP 차단 설정으로 접속 불가\n- `CERT_NOT_REGISTERED_AT_PROVIDER` - 공동인증서가 해당 기관에 미등록 (타기관 인증서 등록 필요)\n\n`실패 카테고리=INVALID_INPUT` (요청·대상 부적합, retryable=false)\n- `INVALID_ACCOUNT_FOR_SERVICE` - 작업과 호환되지 않는 계좌 (예: 대출 미가입 계좌의 대출내역 조회)\n- `INVALID_CARD_FOR_SERVICE` - 조회 대상 카드번호 확인 불가 (보유카드 목록·카드 상태 확인 필요)\n- `INVALID_DATE_RANGE` - 조회 가능한 기간 범위 초과\n- `NO_DATA_AVAILABLE` - 수집 가능한 데이터 0건 (기간·필터 조정 필요)\n\n`실패 카테고리=CREDENTIAL_MISSING` (credential lifecycle, retryable=false)\n- `CREDENTIAL_NOT_FOUND` - 참조한 자격증명이 삭제·비활성 (재바인딩·재등록 필요)\n\n`실패 카테고리=TRANSIENT` (일시 장애, 자동 재시도 대상, retryable=true)\n- `RATE_LIMITED` - 기관이 요청을 일시 제한\n- `TIMEOUT` - 응답 지연으로 시간 초과\n- `LOCK_CONTENTION` - 같은 작업이 동시에 실행 중\n- `LOCK_LEASE_LOST` - 실행 중 락 소유권 상실\n- `DUPLICATE_LOGIN` - 같은 계정의 다른 로그인 진행 중\n- `SESSION_EXPIRED` - 로그인 세션 만료\n- `LOGIN_TRANSIENT` - 로그인 중 일시 오류\n- `PROVIDER_DELAYED` - 기관 응답 지연\n- `PROVIDER_TIME_WINDOW` - 현재 기관 이용 가능 시간 아님 (자정 일자전환·새벽 점검 등)\n- `CONCURRENT_SESSION` - 다른 PC·모바일에서 같은 계정 접속 중\n- `ENGINE_CONCURRENCY_LIMIT` - 동시 실행 제한 초과\n- `PROVIDER_RESPONSE_MALFORMED` - 기관 점검·일시적 비정상 응답\n- `PROVIDER_ERROR` - 기관 측 오류로 작업 미완료\n- `ENGINE_CRASHED` - 수집 요청 비정상 종료\n- `JOB_TIMEOUT` - 작업이 시간 내 미완료 (기간 축소 후 재시도)\n- `PENDING_ORPHAN` - 작업이 시작되지 못하고 만료\n- `INTERNAL_ERROR` - 내부 오류\n\n`실패 카테고리=OTHER` (보편 카테고리 미해당, retryable=false)\n- `WORKSPACE_QUOTA_EXCEEDED` - 무료 한도(월 수집 요청 수) 도달\n- `UNKNOWN` - 분류되지 않은 오류 또는 미매핑 값"
          },
          "message" : {
            "type" : "string",
            "description" : "오류 코드에 대응하는 정규화된 한국어 사용자 메시지."
          },
          "retryAfterSeconds" : {
            "type" : [ "integer", "null" ],
            "format" : "int64",
            "description" : "다음 재시도까지 권장하는 최소 대기 시간(초). `LOCK_CONTENTION`은 항상 120이며, caller는 더 긴 자체 지연 정책을 적용할 수 있다."
          },
          "retryable" : {
            "type" : "boolean",
            "description" : "동일 요청을 다시 보낼 수 있는지 여부. `true` 는 같은 조건으로 재시도 가능, `false` 는 입력값·자격증명·사용자 환경 점검이 먼저 필요하다는 뜻이다."
          }
        },
        "required" : [ "category", "code", "message", "retryable" ]
      },
      "Failed" : {
        "allOf" : [ {
          "$ref" : "#/components/schemas/DataJobHttpResponse"
        }, {
          "type" : "object",
          "properties" : {
            "error" : {
              "$ref" : "#/components/schemas/ErrorHttpField"
            }
          },
          "required" : [ "error" ]
        } ],
        "required" : [ "error" ]
      },
      "InProgress" : {
        "allOf" : [ {
          "$ref" : "#/components/schemas/DataJobHttpResponse"
        }, {
          "type" : "object",
          "properties" : {
            "completedTaskCount" : {
              "type" : "integer",
              "format" : "int32",
              "description" : "지금까지 처리가 끝난 단위 수. totalTaskCount 와 함께 진행률 표시에 사용할 수 있으며, 처리가 끝난 단위의 데이터는 GET /data-jobs/{id}/results 에서 부분 결과로 먼저 조회할 수 있습니다.",
              "example" : 12
            },
            "phase" : {
              "type" : "string",
              "description" : "진행 단계. PENDING=대기열, RUNNING=수집중.",
              "enum" : [ "PENDING", "RUNNING" ],
              "example" : "RUNNING"
            },
            "totalTaskCount" : {
              "type" : "integer",
              "format" : "int32",
              "description" : "이번 수집이 처리할 전체 단위 수. 조회 대상(카드·계좌)과 기간 구간별로 나뉘며, 대상 파악 전에는 0.",
              "example" : 73
            }
          },
          "required" : [ "completedTaskCount", "phase", "totalTaskCount" ]
        } ],
        "required" : [ "completedTaskCount", "phase", "totalTaskCount" ]
      },
      "Succeeded" : {
        "allOf" : [ {
          "$ref" : "#/components/schemas/DataJobHttpResponse"
        }, {
          "type" : "object",
          "properties" : {
            "recordCount" : {
              "type" : "integer",
              "format" : "int64",
              "description" : "수집된 레코드 수. 0 이면 처리는 완료됐지만 조회 가능한 데이터가 없는 케이스.",
              "example" : 42
            }
          },
          "required" : [ "recordCount" ]
        } ]
      },
      "DataJobListItemHttpResponse" : {
        "type" : "object",
        "discriminator" : {
          "propertyName" : "kind"
        },
        "properties" : {
          "id" : {
            "type" : "string",
            "format" : "uuid"
          },
          "kind" : {
            "type" : "string"
          },
          "providerCode" : {
            "type" : "string"
          },
          "schema" : {
            "type" : "string"
          }
        },
        "required" : [ "id", "kind", "providerCode", "schema" ]
      },
      "DataJobPageHttpResponse" : {
        "type" : "object",
        "properties" : {
          "items" : {
            "type" : "array",
            "items" : {
              "oneOf" : [ {
                "$ref" : "#/components/schemas/ListFailed"
              }, {
                "$ref" : "#/components/schemas/ListInProgress"
              }, {
                "$ref" : "#/components/schemas/ListSucceeded"
              } ]
            }
          },
          "nextCursor" : {
            "type" : [ "string", "null" ]
          }
        },
        "required" : [ "items" ]
      },
      "ListFailed" : {
        "allOf" : [ {
          "$ref" : "#/components/schemas/DataJobListItemHttpResponse"
        }, {
          "type" : "object",
          "properties" : {
            "error" : {
              "$ref" : "#/components/schemas/ErrorHttpField"
            }
          },
          "required" : [ "error" ]
        } ]
      },
      "ListInProgress" : {
        "allOf" : [ {
          "$ref" : "#/components/schemas/DataJobListItemHttpResponse"
        } ]
      },
      "ListSucceeded" : {
        "allOf" : [ {
          "$ref" : "#/components/schemas/DataJobListItemHttpResponse"
        } ]
      },
      "BankAccountV1Record" : {
        "allOf" : [ {
          "$ref" : "#/components/schemas/ContractRecord"
        }, {
          "type" : "object",
          "properties" : {
            "accountNumber" : {
              "type" : "string"
            },
            "accountNumberFormatted" : {
              "type" : [ "string", "null" ]
            },
            "accountType" : {
              "type" : "string",
              "enum" : [ "CHECKING", "INSTALLMENT_SAVINGS", "TRUST", "FUND", "FOREIGN", "LOAN", "INSURANCE", "PENSION" ]
            },
            "availableBalance" : {
              "type" : [ "number", "null" ]
            },
            "balance" : {
              "type" : [ "number", "null" ]
            },
            "currencyCode" : {
              "type" : "string"
            },
            "displayName" : {
              "type" : [ "string", "null" ]
            },
            "productName" : {
              "type" : [ "string", "null" ]
            }
          },
          "required" : [ "accountNumber", "accountType", "currencyCode" ]
        } ]
      },
      "BankTransactionV1Record" : {
        "allOf" : [ {
          "$ref" : "#/components/schemas/ContractRecord"
        }, {
          "type" : "object",
          "properties" : {
            "accountNumber" : {
              "type" : "string"
            },
            "accountNumberFormatted" : {
              "type" : [ "string", "null" ]
            },
            "accountType" : {
              "type" : "string",
              "enum" : [ "CHECKING", "INSTALLMENT_SAVINGS", "TRUST", "FUND", "FOREIGN", "LOAN", "INSURANCE", "PENSION" ]
            },
            "amount" : {
              "type" : "number"
            },
            "balance" : {
              "type" : [ "number", "null" ]
            },
            "currencyCode" : {
              "type" : "string"
            },
            "description" : {
              "type" : [ "string", "null" ]
            },
            "identifier" : {
              "type" : "string"
            },
            "transactionAt" : {
              "type" : "string",
              "format" : "date-time"
            }
          },
          "required" : [ "accountNumber", "accountType", "amount", "currencyCode", "identifier", "transactionAt" ]
        } ]
      },
      "CardApprovalV1Record" : {
        "allOf" : [ {
          "$ref" : "#/components/schemas/ContractRecord"
        }, {
          "type" : "object",
          "properties" : {
            "approvalNumber" : {
              "type" : "string"
            },
            "approvedAt" : {
              "type" : "string",
              "format" : "date-time"
            },
            "cardNumberMasked" : {
              "type" : "string"
            },
            "installmentMonths" : {
              "type" : [ "integer", "null" ],
              "format" : "int32"
            },
            "lifecycleStage" : {
              "type" : "string",
              "enum" : [ "AUTHORIZED", "CAPTURED", "UNKNOWN" ]
            },
            "merchantAddress" : {
              "type" : [ "string", "null" ]
            },
            "merchantBusinessIdentifier" : {
              "type" : [ "string", "null" ]
            },
            "merchantBusinessType" : {
              "type" : [ "string", "null" ]
            },
            "merchantContactNumber" : {
              "type" : [ "string", "null" ]
            },
            "merchantName" : {
              "type" : "string"
            },
            "merchantRepresentativeName" : {
              "type" : [ "string", "null" ]
            },
            "originalAmount" : {
              "type" : [ "number", "null" ]
            },
            "originalCurrencyCode" : {
              "type" : [ "string", "null" ]
            },
            "overseas" : {
              "type" : "boolean"
            },
            "paymentMethod" : {
              "type" : "string",
              "enum" : [ "SINGLE_PAYMENT", "INSTALLMENT", "CHECK", "OTHER" ]
            },
            "settledAmount" : {
              "type" : "number"
            },
            "settledCurrencyCode" : {
              "type" : "string"
            },
            "status" : {
              "type" : "string",
              "enum" : [ "APPROVED", "CANCELLED", "PARTIALLY_CANCELLED", "DECLINED", "UNKNOWN" ]
            },
            "taxAmount" : {
              "type" : [ "number", "null" ]
            },
            "transactionIdentifier" : {
              "type" : "string"
            }
          },
          "required" : [ "approvalNumber", "approvedAt", "cardNumberMasked", "lifecycleStage", "merchantName", "overseas", "paymentMethod", "settledAmount", "settledCurrencyCode", "status", "transactionIdentifier" ]
        } ]
      },
      "CardV1Record" : {
        "allOf" : [ {
          "$ref" : "#/components/schemas/ContractRecord"
        }, {
          "type" : "object",
          "properties" : {
            "cardName" : {
              "type" : "string"
            },
            "cardNumberMasked" : {
              "type" : "string"
            }
          },
          "required" : [ "cardName", "cardNumberMasked" ]
        } ]
      },
      "CashReceiptPurchaseV1Record" : {
        "allOf" : [ {
          "$ref" : "#/components/schemas/ContractRecord"
        }, {
          "type" : "object",
          "properties" : {
            "approvalNumber" : {
              "type" : "string"
            },
            "businessTypeCode" : {
              "type" : [ "string", "null" ]
            },
            "businessTypeName" : {
              "type" : [ "string", "null" ]
            },
            "contactNumber" : {
              "type" : [ "string", "null" ]
            },
            "deductible" : {
              "type" : [ "string", "null" ]
            },
            "deductionClassificationCode" : {
              "type" : [ "string", "null" ]
            },
            "deductionClassificationName" : {
              "type" : [ "string", "null" ]
            },
            "issueMethod" : {
              "type" : [ "string", "null" ]
            },
            "issueTypeCode" : {
              "type" : [ "string", "null" ]
            },
            "issueTypeName" : {
              "type" : [ "string", "null" ]
            },
            "lotAddress" : {
              "type" : [ "string", "null" ]
            },
            "merchantBusinessIdentifier" : {
              "type" : [ "string", "null" ]
            },
            "merchantClassification" : {
              "type" : [ "string", "null" ]
            },
            "organizationName" : {
              "type" : [ "string", "null" ]
            },
            "roadAddress" : {
              "type" : [ "string", "null" ]
            },
            "supplyAmount" : {
              "type" : "number"
            },
            "taxAmount" : {
              "type" : "number"
            },
            "tip" : {
              "type" : [ "number", "null" ]
            },
            "totalAmount" : {
              "type" : "number"
            },
            "transactionAt" : {
              "type" : "string",
              "format" : "date-time"
            },
            "transactionType" : {
              "type" : [ "string", "null" ]
            }
          },
          "required" : [ "approvalNumber", "supplyAmount", "taxAmount", "totalAmount", "transactionAt" ]
        } ]
      },
      "CashReceiptSalesV1Record" : {
        "allOf" : [ {
          "$ref" : "#/components/schemas/ContractRecord"
        }, {
          "type" : "object",
          "properties" : {
            "approvalNumber" : {
              "type" : "string"
            },
            "issueMethod" : {
              "type" : [ "string", "null" ]
            },
            "issueType" : {
              "type" : [ "string", "null" ]
            },
            "remark" : {
              "type" : [ "string", "null" ]
            },
            "supplyAmount" : {
              "type" : "number"
            },
            "taxAmount" : {
              "type" : "number"
            },
            "tip" : {
              "type" : [ "number", "null" ]
            },
            "totalAmount" : {
              "type" : "number"
            },
            "transactionAt" : {
              "type" : "string",
              "format" : "date-time"
            },
            "transactionType" : {
              "type" : [ "string", "null" ]
            },
            "useType" : {
              "type" : [ "string", "null" ]
            }
          },
          "required" : [ "approvalNumber", "supplyAmount", "taxAmount", "totalAmount", "transactionAt" ]
        } ]
      },
      "ContractRecord" : {
        "discriminator" : {
          "propertyName" : "schema",
          "mapping" : {
            "bank.accounts.cb.v1" : "#/components/schemas/BankAccountV1Record",
            "bank.transactions.cb.v1" : "#/components/schemas/BankTransactionV1Record",
            "hometax.tax-invoices.sales.v1" : "#/components/schemas/TaxInvoiceSalesV1Record",
            "hometax.tax-invoices.purchase.v1" : "#/components/schemas/TaxInvoicePurchaseV1Record",
            "hometax.cash-receipts.sales.v1" : "#/components/schemas/CashReceiptSalesV1Record",
            "hometax.cash-receipts.purchase.v1" : "#/components/schemas/CashReceiptPurchaseV1Record",
            "card.cards.corp.v1" : "#/components/schemas/CardV1Record",
            "card.approvals.corp.v1" : "#/components/schemas/CardApprovalV1Record"
          }
        },
        "properties" : {
          "schema" : {
            "type" : "string"
          }
        },
        "required" : [ "schema" ]
      },
      "DataJobResultsHttpResponse" : {
        "type" : "object",
        "properties" : {
          "data" : {
            "type" : "array",
            "items" : {
              "oneOf" : [ {
                "$ref" : "#/components/schemas/BankAccountV1Record"
              }, {
                "$ref" : "#/components/schemas/BankTransactionV1Record"
              }, {
                "$ref" : "#/components/schemas/CardApprovalV1Record"
              }, {
                "$ref" : "#/components/schemas/CardV1Record"
              }, {
                "$ref" : "#/components/schemas/CashReceiptPurchaseV1Record"
              }, {
                "$ref" : "#/components/schemas/CashReceiptSalesV1Record"
              }, {
                "$ref" : "#/components/schemas/TaxInvoicePurchaseV1Record"
              }, {
                "$ref" : "#/components/schemas/TaxInvoiceSalesV1Record"
              } ]
            }
          },
          "jobId" : {
            "type" : "string",
            "format" : "uuid"
          },
          "schema" : {
            "type" : "string"
          },
          "totalCount" : {
            "type" : "integer",
            "format" : "int32"
          }
        },
        "required" : [ "data", "jobId", "schema", "totalCount" ]
      },
      "TaxInvoicePurchaseV1Record" : {
        "allOf" : [ {
          "$ref" : "#/components/schemas/ContractRecord"
        }, {
          "type" : "object",
          "properties" : {
            "buyerAddress" : {
              "type" : [ "string", "null" ]
            },
            "buyerBusinessIdentifier" : {
              "type" : "string"
            },
            "buyerEmail" : {
              "type" : [ "string", "null" ]
            },
            "buyerEmailSecondary" : {
              "type" : [ "string", "null" ]
            },
            "buyerOrganizationName" : {
              "type" : [ "string", "null" ]
            },
            "buyerRepresentativeName" : {
              "type" : [ "string", "null" ]
            },
            "buyerSubBusinessNumber" : {
              "type" : [ "string", "null" ]
            },
            "invoiceClassification" : {
              "type" : [ "string", "null" ]
            },
            "invoiceKind" : {
              "type" : [ "string", "null" ]
            },
            "issueChannel" : {
              "type" : [ "string", "null" ]
            },
            "issueDate" : {
              "type" : "string",
              "format" : "date"
            },
            "itemName" : {
              "type" : [ "string", "null" ]
            },
            "itemQuantity" : {
              "type" : [ "number", "null" ]
            },
            "itemRemark" : {
              "type" : [ "string", "null" ]
            },
            "itemSpecification" : {
              "type" : [ "string", "null" ]
            },
            "itemSupplyAmount" : {
              "type" : [ "number", "null" ]
            },
            "itemSupplyDate" : {
              "type" : [ "string", "null" ],
              "format" : "date"
            },
            "itemTaxAmount" : {
              "type" : [ "number", "null" ]
            },
            "itemUnitPrice" : {
              "type" : [ "number", "null" ]
            },
            "ntsTransactionId" : {
              "type" : [ "string", "null" ]
            },
            "paymentType" : {
              "type" : [ "string", "null" ]
            },
            "remark" : {
              "type" : [ "string", "null" ]
            },
            "sendDate" : {
              "type" : [ "string", "null" ],
              "format" : "date"
            },
            "supplierAddress" : {
              "type" : [ "string", "null" ]
            },
            "supplierBusinessIdentifier" : {
              "type" : [ "string", "null" ]
            },
            "supplierEmail" : {
              "type" : [ "string", "null" ]
            },
            "supplierOrganizationName" : {
              "type" : [ "string", "null" ]
            },
            "supplierRepresentativeName" : {
              "type" : [ "string", "null" ]
            },
            "supplierSubBusinessNumber" : {
              "type" : [ "string", "null" ]
            },
            "supplyAmount" : {
              "type" : "number"
            },
            "taxAmount" : {
              "type" : "number"
            },
            "totalAmount" : {
              "type" : "number"
            },
            "trusteeBusinessIdentifier" : {
              "type" : [ "string", "null" ]
            },
            "trusteeOrganizationName" : {
              "type" : [ "string", "null" ]
            },
            "writeDate" : {
              "type" : "string",
              "format" : "date"
            }
          },
          "required" : [ "buyerBusinessIdentifier", "issueDate", "supplyAmount", "taxAmount", "totalAmount", "writeDate" ]
        } ]
      },
      "TaxInvoiceSalesV1Record" : {
        "allOf" : [ {
          "$ref" : "#/components/schemas/ContractRecord"
        }, {
          "type" : "object",
          "properties" : {
            "buyerAddress" : {
              "type" : [ "string", "null" ]
            },
            "buyerBusinessIdentifier" : {
              "type" : [ "string", "null" ]
            },
            "buyerEmail" : {
              "type" : [ "string", "null" ]
            },
            "buyerEmailSecondary" : {
              "type" : [ "string", "null" ]
            },
            "buyerOrganizationName" : {
              "type" : [ "string", "null" ]
            },
            "buyerRepresentativeName" : {
              "type" : [ "string", "null" ]
            },
            "buyerSubBusinessNumber" : {
              "type" : [ "string", "null" ]
            },
            "invoiceClassification" : {
              "type" : [ "string", "null" ]
            },
            "invoiceKind" : {
              "type" : [ "string", "null" ]
            },
            "issueChannel" : {
              "type" : [ "string", "null" ]
            },
            "issueDate" : {
              "type" : "string",
              "format" : "date"
            },
            "itemName" : {
              "type" : [ "string", "null" ]
            },
            "itemQuantity" : {
              "type" : [ "number", "null" ]
            },
            "itemRemark" : {
              "type" : [ "string", "null" ]
            },
            "itemSpecification" : {
              "type" : [ "string", "null" ]
            },
            "itemSupplyAmount" : {
              "type" : [ "number", "null" ]
            },
            "itemSupplyDate" : {
              "type" : [ "string", "null" ],
              "format" : "date"
            },
            "itemTaxAmount" : {
              "type" : [ "number", "null" ]
            },
            "itemUnitPrice" : {
              "type" : [ "number", "null" ]
            },
            "ntsTransactionId" : {
              "type" : [ "string", "null" ]
            },
            "paymentType" : {
              "type" : [ "string", "null" ]
            },
            "remark" : {
              "type" : [ "string", "null" ]
            },
            "sendDate" : {
              "type" : [ "string", "null" ],
              "format" : "date"
            },
            "supplierAddress" : {
              "type" : [ "string", "null" ]
            },
            "supplierBusinessIdentifier" : {
              "type" : "string"
            },
            "supplierEmail" : {
              "type" : [ "string", "null" ]
            },
            "supplierOrganizationName" : {
              "type" : [ "string", "null" ]
            },
            "supplierRepresentativeName" : {
              "type" : [ "string", "null" ]
            },
            "supplierSubBusinessNumber" : {
              "type" : [ "string", "null" ]
            },
            "supplyAmount" : {
              "type" : "number"
            },
            "taxAmount" : {
              "type" : "number"
            },
            "totalAmount" : {
              "type" : "number"
            },
            "trusteeBusinessIdentifier" : {
              "type" : [ "string", "null" ]
            },
            "trusteeOrganizationName" : {
              "type" : [ "string", "null" ]
            },
            "writeDate" : {
              "type" : "string",
              "format" : "date"
            }
          },
          "required" : [ "issueDate", "supplierBusinessIdentifier", "supplyAmount", "taxAmount", "totalAmount", "writeDate" ]
        } ]
      }
    },
    "securitySchemes" : {
      "ApiKeyBearer" : {
        "type" : "http",
        "description" : "API Key 토큰 (`Authorization: Bearer h6s_live_...`)",
        "scheme" : "bearer"
      }
    }
  }
}