본문으로 건너뛰기

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

필드 설명

필드타입필수설명
resumeDataobject이력서 데이터.
resumeData.typestringtext, html, pdf, docx 중 하나.
resumeData.contentstring텍스트/HTML은 UTF-8, pdf/docx는 base64 인코딩(요청 크기 10MB 제한).
jobPostingDataobject채용 공고 데이터(resumeData와 동일한 스키마).
optionsobject아니요선택 설정 컨테이너.
options.webhookobject아니요완료 웹훅 설정.
options.webhook.urlstringHTTPS 엔드포인트.
options.webhook.secretstring아니요선택적 서명 시크릿(32~64자 권장).
X-Request-ID (멱등성)

최대 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
}

응답 필드

필드타입설명
idstring폴링/조회에 사용하는 분석 ID.
statusstring초기 상태로 QUEUED 반환.
estimatedTimeinteger예상 처리 시간(초). 기본값 30, 이후 갱신되지 않음.
webhookobject/null설정한 웹훅 정보와 전달 현황.
links.selfstring분석 리소스 URL.
metadata.creditsUsedinteger예약된 크레딧 수(실서비스 분석은 항상 1).
크레딧 예약

요청이 수락되면 1크레딧이 우선 예약되고, 분석이 성공적으로 완료될 때만 차감됩니다. 실패한 분석은 추가 크레딧을 소비하지 않습니다.

분석 조회

현재 상태 또는 완료 결과를 조회합니다.

엔드포인트

GET /public/v1/analyses/{analysisId}

경로 변수

변수타입설명
analysisIdstring생성 시 반환된 분석 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
}

응답 필드

필드타입설명
statusstringQUEUED, PROCESSING, COMPLETED, FAILED 중 하나.
createdAtstring분석이 접수된 시각(ISO 8601).
completedAtstring/null완료 시각. 처리 중에는 null.
processingTimeinteger/null완료/실패 시의 처리 시간(ms).
estimatedTimeinteger/null처리 중 남은 시간(초). 완료/실패 후에는 생략.
resultobject/nullCOMPLETED 상태에서 결과 객체가 포함되며, 아래 노트를 참고하세요.
errorobject/nullFAILED 상태일 때 오류 코드와 메시지.
metadata.creditsUsedinteger/null수락 또는 완료 시점에만 제공됩니다. 처리 중이거나 실패하면 생략되어 크레딧이 차감되지 않았음을 의미합니다.
webhook.deliveryobject/null전달 상태(state, lastAttemptAt, lastStatusCode, attemptCount, lastError).
links.selfstring후속 폴링에 사용하는 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_KEY401Miri-Api-Key 헤더 누락 또는 형식 오류.
AUTH001401인증 실패.
AUTH003403키가 일시 중지 또는 폐기됨.
VAL001400지원하지 않는 콘텐츠 타입 또는 JSON 파싱 실패.
VAL002400필수 필드(resumeData, jobPostingData 등) 누락.
VAL003400필드 검증 실패(열거형/UUID 등).
VAL004400페이로드 크기 제한 초과(base64 10MB 한도).
BUS002402크레딧 부족. metadatarequired, available, purchaseUrl 포함.
NOT001404분석을 찾을 수 없음(실서비스 및 샌드박스 공통).
SVC001503일시적 플랫폼 장애.
SVC002503회로 차단기가 열림.
SVC003503종속 서비스 타임아웃.
INT001500예기치 않은 서버 오류.

관련 엔드포인트

  • 배치 API – 여러 분석을 한 번에 제출
  • 결제 API – 분석에 필요한 크레딧 충전