본문으로 건너뛰기

배치 분석 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"
}
}
}

필드 설명

필드타입필수설명
analysesarray분석 항목 배열(1~100건).
analyses[].referenceIdstring상태 응답에 그대로 반환되는 파트너 식별자.
analyses[].resumeDataobject단일 분석 API와 동일한 스키마.
analyses[].resumeData.contentstringtext/html은 UTF-8, pdf/docx는 base64 인코딩(10MB 제한).
analyses[].jobPostingDataobject단일 분석 API와 동일한 스키마.
analyses[].jobPostingData.contentstringtext/html은 UTF-8, pdf/docx는 base64 인코딩.
optionsobject아니요배치 전체 설정.
options.parallelinteger아니요최대 동시 작업 수(1~50, 기본값 10).
options.webhookobject아니요배치 웹훅 설정.
options.webhook.urlstringHTTPS 엔드포인트.
options.webhook.secretstring아니요선택적 서명 시크릿.

응답 (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
}

응답 필드

필드타입설명
idstring배치 상태 조회에 사용하는 ID.
totalCountinteger제출한 분석 수.
estimatedTimeintegertotalCount × 30초로 계산되며 이후 갱신되지 않음.
webhookobject/null설정한 웹훅 정보와 전달 현황.
links.selfstring배치 상태 조회 URL.
links.cancelstring배치 취소 URL(self와 동일).
metadata.creditsUsedinteger수락 시 예약된 크레딧 수. 처리 중이거나 실패한 경우 생략될 수 있습니다.
크레딧 사용량

배치가 수락되면 항목당 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
}

필드 설명

필드타입설명
statusstringQUEUED, PROCESSING, COMPLETED, PARTIAL, FAILED, CANCELLED.
completedCountinteger성공적으로 완료된 항목 수.
failedCountinteger실패한 항목 수.
progressPercentageinteger전체 진행률(%)
items[].statusstringPENDING, PROCESSING, COMPLETED, FAILED.
items[].analysisIdstring/null생성된 단일 분석 ID.
items[].errorobject/null실패 상세(codePROCESSING_ERROR, CANCELLED 등).
metadata.creditsUsedinteger배치 전체에 예약된 크레딧. 처리 중이거나 실패한 경우 생략될 수 있습니다.
크레딧 예약

metadata.creditsUsed 값은 예약된 총 크레딧을 나타내며, 실제 차감은 각 분석이 완료될 때 이루어집니다. FAILED 항목은 자동으로 환불됩니다.

배치 취소

DELETE /public/v1/analyses/batch/{batchId}
  • 요청이 수락되면 204 No Content를 반환합니다.
  • statusQUEUED 또는 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_KEY401Miri-Api-Key 누락 또는 형식 오류.
AUTH001401API 키 인증 실패.
AUTH003403키 정지 상태.
VAL001400요청 JSON 파싱 실패.
VAL002400필수 필드 누락.
VAL003400필드 검증 실패(타입/범위 등).
VAL004400페이로드 크기 또는 배치 건수 제한 초과.
BUS002402배치를 예약할 크레딧 부족.
NOT001404배치를 찾을 수 없음(실서비스/샌드박스 공통).
SVC001503일시적 플랫폼 장애.
SVC002503회로 차단기가 열림.
SVC003503종속 서비스 타임아웃.
INT001500예기치 않은 서버 오류.

관련 엔드포인트