분석 API
이 엔드포인트는 단일 이력서와 채용 공고를 프리미엄 분석 파이프라인에 제출합니다. 응답은 비동기로 처리되며, 수락 시 반환되는 ID를 통해 폴링하거나 웹훅으로 결과를 받을 수 있습니다.
인증
Miri-Api-Key: miri_live_sk_xxxxxxxxxxxxxxxxxxxxxxxx.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
모든 요청은 유효한 MIRI API 키를 필요로 합니다. 재시도 시 멱등성을 보장하려면 X-Request-ID 헤더를 추가하세요.
분석 생성
단일 이력서/채용 공고 쌍을 분석합니다.
엔드포인트
POST /public/v1/analyses
헤더
Miri-Api-Key: miri_live_sk_xxxxxxxxxxxxxxxxxxxxxxxx.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Content-Type: application/json
X-Request-ID: 6dc2d2d2-5a72-4b47-9f9c-8f6aa2a9244e (선택)
요청 본문
text/html은 UTF-8 텍스트, pdf/docx는 base64 인코딩을 사용하세요. 전체 요청 크기는 10MB를 초과할 수 없습니다.
{
"resumeData": {
"type": "pdf",
"content": "UEsDBBQABgAIAAAAIQAAAAAAAAAAAAAAAAAJAAAAdXJsLnR4dFxTZW5pb3IgcmVzdW1lIHNhbXBsZS4uLg=="
},
"jobPostingData": {
"type": "html",
"content": "<h1>Senior Backend Engineer</h1><p>서비스 설계...</p>"
},
"options": {
"webhook": {
"url": "https://partner.example.com/hooks",
"secret": "optional-hmac-secret"
}
}
}
필드 설명
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
resumeData | object | 예 | 이력서 데이터. |
resumeData.type | string | 예 | text, html, pdf, docx 중 하나. |
resumeData.content | string | 예 | 텍스트/HTML은 UTF-8, pdf/docx는 base64 인코딩(요청 크기 10MB 제한). |
jobPostingData | object | 예 | 채용 공고 데이터(resumeData와 동일한 스키마). |
options | object | 아니요 | 선택 설정 컨테이너. |
options.webhook | object | 아니요 | 완료 웹훅 설정. |
options.webhook.url | string | 예 | HTTPS 엔드포인트. |
options.webhook.secret | string | 아니요 | 선택적 서명 시크릿(32~64자 권장). |
최대 255자 ASCII 문자열(권장: UUID v4)을 X-Request-ID에 전달하면 안전한 재시도가 보장됩니다. 동일한 값으로 재요청하면 기존 분석의 최신 상태(PROCESSING, COMPLETED, FAILED)를 그대로 반환하며 추가 크레딧은 차감되지 않습니다.
응답 (202 Accepted)
{
"success": true,
"data": {
"id": "0199d5b8-3a2f-4f62-8f4d-9c4fdfb7c2a1",
"status": "QUEUED",
"estimatedTime": 30,
"createdAt": "2025-09-19T10:15:23.456Z",
"webhook": {
"url": "https://partner.example.com/hooks",
"delivery": {
"state": "PENDING",
"lastAttemptAt": null,
"lastStatusCode": null,
"attemptCount": 0,
"lastError": null
}
},
"links": {
"self": "/public/v1/analyses/0199d5b8-3a2f-4f62-8f4d-9c4fdfb7c2a1"
},
"metadata": {
"creditsUsed": 1
}
},
"message": null,
"code": "SUCCESS",
"metadata": null
}
응답 필드
| 필드 | 타입 | 설명 |
|---|---|---|
id | string | 폴링/조회에 사용하는 분석 ID. |
status | string | 초기 상태로 QUEUED 반환. |
estimatedTime | integer | 예상 처리 시간(초). 기본값 30, 이후 갱신되지 않음. |
webhook | object/null | 설정한 웹훅 정보와 전달 현황. |
links.self | string | 분석 리소스 URL. |
metadata.creditsUsed | integer | 예약된 크레딧 수(실서비스 분석은 항상 1). |
요청이 수락되면 1크레딧이 우선 예약되고, 분석이 성공적으로 완료될 때만 차감됩니다. 실패한 분석은 추가 크레딧을 소비하지 않습니다.
분석 조회
현재 상태 또는 완료 결과를 조회합니다.
엔드포인트
GET /public/v1/analyses/{analysisId}
경로 변수
| 변수 | 타입 | 설명 |
|---|---|---|
analysisId | string | 생성 시 반환된 분석 ID. |
응답 (200 OK)
{
"success": true,
"data": {
"id": "0199f6ac-5c23-41b0-904b-6b9f7c5f2c11",
"status": "COMPLETED",
"createdAt": "2025-09-19T10:15:23.456Z",
"completedAt": "2025-09-19T10:16:45.123Z",
"processingTime": 82031,
"estimatedTime": null,
"result": {
"analysis": { "experience": { "score": 0.82, "comments": { "applicant_perspective": "채용 공고와 연결된 성과를 강조하세요." } } },
"essential": { "skillAnalysisResults": [] },
"preferred": { "skillAnalysisResults": [] },
"interviewQuestions": [],
"overallEvaluation": {
"feedback": [],
"recommendations": [],
"improvementSuggestionsForApplicant": [],
"resumeFeedback": [],
"coverLetterFeedback": []
}
},
"metadata": {
"creditsUsed": 1
},
"webhook": {
"url": "https://partner.example.com/hooks",
"delivery": {
"state": "SUCCESS",
"lastAttemptAt": "2025-09-19T10:16:45.500Z",
"lastStatusCode": 200,
"attemptCount": 1,
"lastError": null
}
},
"links": {
"self": "/public/v1/analyses/0199f6ac-5c23-41b0-904b-6b9f7c5f2c11"
}
},
"message": null,
"code": "SUCCESS",
"metadata": null
}
응답 필드
| 필드 | 타입 | 설명 |
|---|---|---|
status | string | QUEUED, PROCESSING, COMPLETED, FAILED 중 하나. |
createdAt | string | 분석이 접수된 시각(ISO 8601). |
completedAt | string/null | 완료 시각. 처리 중에는 null. |
processingTime | integer/null | 완료/실패 시의 처리 시간(ms). |
estimatedTime | integer/null | 처리 중 남은 시간(초). 완료/실패 후에는 생략. |
result | object/null | COMPLETED 상태에서 결과 객체가 포함되며, 아래 노트를 참고하세요. |
error | object/null | FAILED 상태일 때 오류 코드와 메시지. |
metadata.creditsUsed | integer/null | 수락 또는 완료 시점에만 제공됩니다. 처리 중이거나 실패하면 생략되어 크레딧이 차감되지 않았음을 의미합니다. |
webhook.delivery | object/null | 전달 상태(state, lastAttemptAt, lastStatusCode, attemptCount, lastError). |
links.self | string | 후속 폴링에 사용하는 URL. |
result 객체에는 섹션별 가이드(analysis.*), 필수/선호 스킬 추천(essential, preferred), 인터뷰 질문, overallEvaluation 피드백이 포함됩니다. 이 값은 이후 재조회 시에도 변하지 않습니다.
샌드박스 테스트
실서비스 크레딧을 소비하지 않고 통합 경로를 검증합니다.
샌드박스 분석 생성
POST /public/v1/analyses/test-run
- 헤더와 요청 스키마는 실서비스 엔드포인트와 동일합니다.
- 응답은 즉시 반환되며
metadata.creditsUsed = 0으로 고정됩니다. - 샌드박스 ID는 10분 후 만료되며 만료 시
NOT001을 반환합니다.
샌드박스 결과 조회
GET /public/v1/analyses/test-run/{analysisId}
샌드박스 응답은 생산 환경과 동일한 스키마를 따르지만, 항상 결정적인 더미 데이터를 제공합니다. 이 ID는 GET /public/v1/analyses/{id}에서 인식되지 않습니다.
웹훅 이벤트
options.webhook을 지정하면 분석 수명주기 동안 다음 이벤트가 발송됩니다.
analysis.completed— 결과가 저장된 직후 전송됩니다.analysis.failed— 처리 과정이 실패로 종료되면 전송됩니다.
각 전송은 이벤트 이름과 발생 시각(초 단위 epoch)을 포함한 래퍼로 감싸지며, 본문에는 분석 정보를 제공합니다.
{
"event": "analysis.completed",
"timestamp": 1758407305,
"data": {
"id": "0199f6ac-5c23-41b0-904b-6b9f7c5f2c11",
"type": "analysis",
"status": "COMPLETED"
}
}
실패 알림은 동일한 구조를 사용하고 data.error에 실패 원인을 포함합니다. 요청 헤더는 다음과 같습니다.
X-Webhook-Event: 이벤트 이름(예:analysis.completed).X-Webhook-Timestamp: 전송 시각(밀리초 기준 epoch).X-Webhook-Signature:webhook.secret을 설정했을 때 제공되는 HMAC-SHA256 서명.
재시도는 2초 간격으로 최대 3회 수행되며, 최신 시도 결과는 폴링 응답의 webhook.delivery(state, lastStatusCode, attemptCount, lastError)에서 확인할 수 있습니다.
오류 코드
| 코드 | HTTP 상태 | 설명 |
|---|---|---|
INVALID_API_KEY | 401 | Miri-Api-Key 헤더 누락 또는 형식 오류. |
AUTH001 | 401 | 인증 실패. |
AUTH003 | 403 | 키가 일시 중지 또는 폐기됨. |
VAL001 | 400 | 지원하지 않는 콘텐츠 타입 또는 JSON 파싱 실패. |
VAL002 | 400 | 필수 필드(resumeData, jobPostingData 등) 누락. |
VAL003 | 400 | 필드 검증 실패(열거형/UUID 등). |
VAL004 | 400 | 페이로드 크기 제한 초과(base64 10MB 한도). |
BUS002 | 402 | 크레딧 부족. metadata에 required, available, purchaseUrl 포함. |
NOT001 | 404 | 분석을 찾을 수 없음(실서비스 및 샌드박스 공통). |
SVC001 | 503 | 일시적 플랫폼 장애. |
SVC002 | 503 | 회로 차단기가 열림. |
SVC003 | 503 | 종속 서비스 타임아웃. |
INT001 | 500 | 예기치 않은 서버 오류. |