배치 분석 API
여러 이력서–채용 공고 쌍을 한 번에 제출해 단일 분석 API와 동일한 프리미엄 파이프라인을 실행합니다.
인증
Miri-Api-Key: miri_live_sk_xxxxxxxxxxxxxxxxxxxxxxxx.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
모든 배치 요청에는 유효한 MIRI API 키가 필요합니다. 배치 단위 재시도를 방지하려면 X-Request-ID를 사용하세요.
배치 생성
엔드포인트
POST /public/v1/analyses/batch
헤더
Miri-Api-Key: miri_live_sk_xxxxxxxxxxxxxxxxxxxxxxxx.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Content-Type: application/json
X-Request-ID: 3f3e6d77-9ad3-4ec8-81ad-308b74fb8193 (선택)
요청 본문
콘텐츠 인코딩
각 항목은 분석 API와 동일한 규칙을 따릅니다. text/html은 UTF-8, pdf/docx는 base64 인코딩을 사용하며 전체 요청 크기는 10MB를 초과할 수 없습니다.
{
"analyses": [
{
"referenceId": "candidate-001",
"resumeData": {
"type": "pdf",
"content": "UEsDBBQABgAIAAAAIQAAAAAAAAAAAAAAAAAJAAAAdXJsLnR4dFxTZW5pb3IgcmVzdW1lIHNhbXBsZS4uLg=="
},
"jobPostingData": {
"type": "html",
"content": "<h1>Principal Backend Engineer</h1><p>서비스 확장...</p>"
}
}
],
"options": {
"parallel": 20,
"webhook": {
"url": "https://partner.example.com/webhooks/batch",
"secret": "optional-hmac-secret"
}
}
}
필드 설명
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
analyses | array | 예 | 분석 항목 배열(1~100건). |
analyses[].referenceId | string | 예 | 상태 응답에 그대로 반환되는 파트너 식별자. |
analyses[].resumeData | object | 예 | 단일 분석 API와 동일한 스키마. |
analyses[].resumeData.content | string | 예 | text/html은 UTF-8, pdf/docx는 base64 인코딩(10MB 제한). |
analyses[].jobPostingData | object | 예 | 단일 분석 API와 동일한 스키마. |
analyses[].jobPostingData.content | string | 예 | text/html은 UTF-8, pdf/docx는 base64 인코딩. |
options | object | 아니요 | 배치 전체 설정. |
options.parallel | integer | 아니요 | 최대 동시 작업 수(1~50, 기본값 10). |
options.webhook | object | 아니요 | 배치 웹훅 설정. |
options.webhook.url | string | 예 | HTTPS 엔드포인트. |
options.webhook.secret | string | 아니요 | 선택적 서명 시크릿. |
응답 (202 Accepted)
{
"success": true,
"data": {
"id": "b59c996e-4d0e-4c08-840a-5a0b4b2bb691",
"status": "QUEUED",
"totalCount": 25,
"estimatedTime": 750,
"createdAt": "2025-09-19T10:15:23.456Z",
"webhook": {
"url": "https://partner.example.com/webhooks/batch",
"delivery": {
"state": "PENDING",
"lastAttemptAt": null,
"lastStatusCode": null,
"attemptCount": 0,
"lastError": null
}
},
"links": {
"self": "/public/v1/analyses/batch/b59c996e-4d0e-4c08-840a-5a0b4b2bb691",
"cancel": "/public/v1/analyses/batch/b59c996e-4d0e-4c08-840a-5a0b4b2bb691"
},
"metadata": {
"creditsUsed": 25
}
},
"message": null,
"code": "SUCCESS",
"metadata": null
}
응답 필드
| 필드 | 타입 | 설명 |
|---|---|---|
id | string | 배치 상태 조회에 사용하는 ID. |
totalCount | integer | 제출한 분석 수. |
estimatedTime | integer | totalCount × 30초로 계산되며 이후 갱신되지 않음. |
webhook | object/null | 설정한 웹훅 정보와 전달 현황. |
links.self | string | 배치 상태 조회 URL. |
links.cancel | string | 배치 취소 URL(self와 동일). |
metadata.creditsUsed | integer | 수락 시 예약된 크레딧 수. 처리 중이거나 실패한 경우 생략될 수 있습니다. |
크레딧 사용량
배치가 수락되면 항목당 1크레딧이 즉시 예약됩니다. 실패 항목은 자동 환불되므로 결과는 items[].status를 통해 확인하세요.
배치 상태 조회
엔드포인트
GET /public/v1/analyses/batch/{batchId}
응답 (200 OK)
{
"success": true,
"data": {
"id": "b59c996e-4d0e-4c08-840a-5a0b4b2bb691",
"status": "PROCESSING",
"totalCount": 25,
"completedCount": 12,
"failedCount": 1,
"progressPercentage": 52,
"items": [
{
"referenceId": "candidate-001",
"status": "COMPLETED",
"analysisId": "0199f6ac-5c23-41b0-904b-6b9f7c5f2c11",
"error": null
},
{
"referenceId": "candidate-002",
"status": "FAILED",
"analysisId": null,
"error": {
"code": "PROCESSING_ERROR",
"message": "Input validation failed"
}
}
],
"createdAt": "2025-09-19T10:15:23.456Z",
"startedAt": "2025-09-19T10:15:24.010Z",
"completedAt": null,
"webhook": {
"url": "https://partner.example.com/webhooks/batch",
"delivery": {
"state": "PENDING",
"lastAttemptAt": null,
"lastStatusCode": null,
"attemptCount": 0,
"lastError": null
}
},
"links": {
"self": "/public/v1/analyses/batch/b59c996e-4d0e-4c08-840a-5a0b4b2bb691",
"cancel": "/public/v1/analyses/batch/b59c996e-4d0e-4c08-840a-5a0b4b2bb691"
},
"metadata": {
"creditsUsed": 25
}
},
"message": null,
"code": "SUCCESS",
"metadata": null
}
필드 설명
| 필드 | 타입 | 설명 |
|---|---|---|
status | string | QUEUED, PROCESSING, COMPLETED, PARTIAL, FAILED, CANCELLED. |
completedCount | integer | 성공적으로 완료된 항목 수. |
failedCount | integer | 실패한 항목 수. |
progressPercentage | integer | 전체 진행률(%) |
items[].status | string | PENDING, PROCESSING, COMPLETED, FAILED. |
items[].analysisId | string/null | 생성된 단일 분석 ID. |
items[].error | object/null | 실패 상세(code는 PROCESSING_ERROR, CANCELLED 등). |
metadata.creditsUsed | integer | 배치 전체에 예약된 크레딧. 처리 중이거나 실패한 경우 생략될 수 있습니다. |
크레딧 예약
metadata.creditsUsed 값은 예약된 총 크레딧을 나타내며, 실제 차감은 각 분석이 완료될 때 이루어집니다. FAILED 항목은 자동으로 환불됩니다.
배치 취소
DELETE /public/v1/analyses/batch/{batchId}
- 요청이 수락되면
204 No Content를 반환합니다. status가QUEUED또는PROCESSING일 때만 취소 가능합니다.- 대기 중인 항목은
FAILED로 전환되며error.code = "CANCELLED"가 설정됩니다.
샌드박스 엔드포인트
크레딧 없이 통합을 검증할 수 있습니다.
샌드박스 배치 생성
POST /public/v1/analyses/batch/test-run
- 요청 스키마는 실서비스와 동일합니다.
- 응답은 결정적인 샘플 데이터를 제공하며
metadata.creditsUsed = 0입니다. - 샌드박스 배치는 10분 후 만료(
NOT001).
샌드박스 배치 조회
GET /public/v1/analyses/batch/test-run/{batchId}
샌드박스 분석 ID는 샌드박스 전용이며 실서비스 엔드포인트에서는 사용할 수 없습니다.
웹훅 이벤트
options.webhook.url을 설정하면 다음 이벤트가 발송됩니다.
- 각 항목 완료 시
analysis.completed,analysis.failed - 모든 항목이 종료 상태에 도달하면
batch.completed
전달 정책은 단일 분석 API와 동일합니다(최대 3회, 2초 간격 재시도). 전달 결과는 응답의 webhook.delivery에 반영됩니다.
오류 코드
| 코드 | HTTP 상태 | 설명 |
|---|---|---|
INVALID_API_KEY | 401 | Miri-Api-Key 누락 또는 형식 오류. |
AUTH001 | 401 | API 키 인증 실패. |
AUTH003 | 403 | 키 정지 상태. |
VAL001 | 400 | 요청 JSON 파싱 실패. |
VAL002 | 400 | 필수 필드 누락. |
VAL003 | 400 | 필드 검증 실패(타입/범위 등). |
VAL004 | 400 | 페이로드 크기 또는 배치 건수 제한 초과. |
BUS002 | 402 | 배치를 예약할 크레딧 부족. |
NOT001 | 404 | 배치를 찾을 수 없음(실서비스/샌드박스 공통). |
SVC001 | 503 | 일시적 플랫폼 장애. |
SVC002 | 503 | 회로 차단기가 열림. |
SVC003 | 503 | 종속 서비스 타임아웃. |
INT001 | 500 | 예기치 않은 서버 오류. |