• 기능 제공 요금제: 엔터프라이즈(유료)
• 기능 사용 권한: '웹훅/API 연동' 관리 권한을 가진 멤버 (API 키 발급·삭제)
1. 나인하이어 API
나인하이어 API는 포지션(공고), 직군·근무지·소속, 지원자 정보를 조회하고 외부 채널에서 받은 지원자를 등록할 수 있는 REST API입니다. 나인하이어 API를 통해 나인하이어에 등록한 공고와 관련 정보를 외부 애플리케이션에서 연동해 보세요. 자사 채용 홈페이지나 사이트 위젯 등에서 실시간으로 공고 정보를 제공하거나, 지원자 정보를 수집하고자 할 때, 나인하이어 API를 사용하실 수 있습니다.
나인하이어 API는 아래 9개를 제공합니다. v2는 포지션 조회 2개만 제공하며, 그 외 기능은 v1을 사용합니다.
버전 | 메서드 | 경로 | 설명 |
v1 | GET |
| 포지션 목록 조회 |
v1 | GET |
| 포지션 상세 조회 |
v1 | GET |
| 직군 목록 조회 |
v1 | GET |
| 근무지 목록 조회 |
v1 | GET |
| 소속 목록 조회 |
v1 | GET |
| 포지션별 지원자 목록 조회 |
v1 | POST |
| 포지션에 지원자 등록 |
v2 | GET |
| 포지션 목록 조회 (포지션 상태·접수 상태 분리) |
v2 | GET |
| 포지션 상세 조회 (포지션 상태·접수 상태 분리) |
⚠️ 워크스페이스 요금제가 엔터프라이즈 미만으로 변경되거나 구독이 해지되면, 발급된 API 키와 등록된 웹훅이 모두 삭제됩니다. 요금제를 다시 적용한 뒤에는 API 키를 새로 발급하고 웹훅 등록을 다시 요청해 주세요.
💡 나인하이어 MCP(AI 에이전트 연동) 기능은 별도의 MCP 연동용 키를 사용하며, 이 가이드에서 다루지 않습니다.
2. API 인증하기
나인하이어 API를 사용하시기 위해서는 인증이 반드시 포함되어야 합니다. 나인하이어의 워크스페이스별로 발급되는 고유한 API 키를 사용하여 인증합니다.
1) API 키 발급받기
• API 키 발급 경로: 설정 → 외부 서비스 연동 → [API 연동]
[API 키 발급받기] 버튼을 클릭하여 인증 키를 발급받으실 수 있습니다. 발급받으신 API 키는 외부에 노출이 되지 않도록 주의하시기를 바랍니다. API 키는 워크스페이스당 1개만 발급할 수 있습니다. 키를 바꾸려면 기존 키를 삭제한 뒤 다시 발급해 주세요. 삭제한 키는 즉시 사용할 수 없습니다.
API 키는 워크스페이스(회사) 단위로 발급되며 특정 멤버에게 귀속되지 않습니다. 키를 발급한 멤버가 비활성화되어도 키는 유효하며, 삭제하기 전까지 만료되지 않습니다.
💡 이미 API 키가 발급되어 있는 경우 [API 키 발급받기] 버튼은 회색으로 비활성화되며, 버튼 아래에 기존 API 키가 표시됩니다. 표시된 키를 그대로 복사해서 사용하시면 됩니다. 기존 키를 삭제하고 재발급하면, 연동 시스템에 새 키를 반영하기 전까지 API 호출이 실패합니다. 키를 교체할 때는 기존 키 삭제 → 신규 발급 → 연동 시스템 설정 교체 순으로 진행해 주세요.
2) API 인증 방식
API 요청 시 발급받은 API 키를 Authorization 헤더에 포함하여 인증해 주세요. API 키는 소스코드에 배포되거나 외부에 노출되지 않도록 주의하여 주시기 바랍니다.
JSON
Authorization: Bearer {API_KEY}
Bearer와 API 키 사이는 공백 한 칸으로 구분합니다. API 키가 워크스페이스를 식별하므로 회사 ID 등 별도 파라미터는 필요하지 않습니다.
API 키는 비밀번호와 같이 취급해 주세요. 소스 코드 저장소, 브라우저·앱 코드, 로그에 남기지 말고 서버 측 비밀 저장소에 보관해 주세요.
3. API 요청 공통 규칙
1) Base URL
https://api.ninehire.com/api/v1
https://api.ninehire.com/api/v2
모든 API 경로는 버전별 Base URL 뒤에 붙습니다. (예: https://api.ninehire.com/api/v1/jobs)
v2는 포지션 목록·상세 조회만 제공하므로, 그 외 API는 v1 Base URL을 사용해 주세요. 인증, 요청·응답 형식, 요청 제한 등 공통 규칙은 v1·v2에 똑같이 적용됩니다.
2) 요청 형식
항목 | 내용 |
프로토콜 | HTTPS |
조회(GET) 파라미터 | URL 쿼리 문자열. 배열 파라미터는 같은 키를 반복합니다. (예: |
등록(POST) 본문 |
|
불리언 쿼리 값 | 문자열 |
정의되지 않은 쿼리 파라미터 | 무시됩니다. |
3) 응답 형식
모든 응답 본문은 JSON(UTF-8)입니다. 단, 지원자 등록 API의 성공 응답은 본문이 없습니다.
목록 조회 API는 아래 구조로 응답합니다. count는 현재 페이지 건수가 아닌, 조회 조건에 해당하는 전체 건수입니다.
{
"count": 37,
"results": [ ... ]
}
4) 날짜·시간 형식
구분 | 형식 | 예시 | 적용 필드 |
일시 | ISO 8601, UTC, 밀리초 포함 |
|
|
날짜 |
|
| 지원자 생년월일( |
일시 값은 모두 UTC로 제공되므로, 화면 표시나 날짜 비교 시 한국 시간(UTC+9)으로 변환해 주세요.
입학일·졸업일 등 지원자가 날짜로 입력한 값도 UTC 일시로 제공됩니다. 예를 들어 한국 시간 2008-03-01은 2008-02-29T15:00:00.000Z로 표시되므로, UTC+9로 변환한 뒤 날짜 부분을 사용해 주세요.
5) 빈 값 처리
값이 없을 수 있는 필드(nullable)는 값이 없을 때
null로 제공되며, 필드 자체가 생략되지는 않습니다.배열 필드는 값이 없을 때 빈 배열
[]로 제공됩니다.
6) 페이지네이션
목록 조회 API는 page(페이지 번호, 1부터 시작)와 countPerPage(페이지당 건수)로 페이지를 지정합니다.
API | page 기본값 | countPerPage 기본값 | countPerPage 최대값 |
포지션 목록 조회 (v1·v2) | 1 | 10 | 100 (초과 값은 100으로 처리) |
지원자 목록 조회 | 1 | 10 | 100 (초과 값은 100으로 처리) |
직군·근무지·소속 목록 조회 | 1 | 20 | 별도 상한 없음 (100 이하 권장) |
page, countPerPage에는 1 이상의 정수를 입력해 주세요. 0이나 숫자가 아닌 값은 기본값으로 처리됩니다.
전체 페이지 수는 count를 countPerPage로 나눈 뒤 올림한 값입니다.
페이지를 순회하는 동안 데이터가 추가·변경되면 항목이 중복되거나 누락될 수 있습니다. 대량 조회 시 11. 권장 연동 방식을 참고해 주세요.
4. API 응답
API의 응답 성공 여부는 HTTP 상태 코드로 전달되어 HTTP 상태 코드에 따라 요청이나 에러를 처리하는 로직을 구현하실 수 있습니다.
1) HTTP 상태 코드
코드 | 의미 | 발생 조건 |
400 | 필수 파라미터 누락 | 지원자 목록 조회에 |
401 | 인증 실패 |
|
404 | 등록된 키 없음 | 삭제되었거나 재발급으로 교체된 키로 호출 |
404 | 리소스 없음 | 조회·등록 대상 포지션이 없거나 삭제됨, 포지션에 전형 단계가 없음, 워크스페이스 개인정보 보호 설정을 찾지 못함, 정의되지 않은 경로로 호출 |
422 | 파일명 확장자 없음 | 지원자 등록 시 |
429 | 요청 한도 초과 | 워크스페이스 또는 IP 기준 요청 한도 초과 (오류 코드 |
500 | 서버 오류 | 처리 중 예기치 못한 오류 (요청 본문 구조가 명세와 다른 경우 포함) |
오류 응답 본문은 오류 종류에 따라 구조가 다릅니다. HTTP 상태 코드로 분기해 주세요. message 문구는 예고 없이 바뀔 수 있으므로 로그 확인 용도로만 사용해 주세요.
HTTP 상태 | 본문 구조 |
400, 401, 422, 500 |
|
404(리소스 없음), 429 |
|
404(정의되지 않은 경로) |
|
인증 검사는 요청 파라미터 검사보다 먼저 수행됩니다. 예를 들어 API 키가 잘못되었고 jobId도 없으면 401이 반환됩니다.
2) 요청 제한 (Rate Limit)
API는 안정적인 서비스 운영을 위해 아래 두 가지 요청 제한이 동시에 적용됩니다.
제한 | 기준 | 한도 |
워크스페이스 한도 | API 키로 인증된 워크스페이스 | 60초에 60회 |
IP 한도 | 요청을 보낸 IP | 60초에 120회 |
두 한도 모두 직전 60초 동안의 요청 수로 계산됩니다(슬라이딩 윈도우). 워크스페이스 한도는 API별로 따로 적용되지 않고, 같은 워크스페이스에서 호출하는 모든 API(v1·v2, MCP 연동 호출 포함)를 합산해 적용됩니다. (예: 포지션 목록 조회와 지원자 목록 조회를 함께 호출하면 두 호출을 합산해 60초 60회로 계산됩니다.) IP 한도는 인증 결과와 관계없이 해당 IP에서 들어온 요청 전체에 적용됩니다.
제한을 초과하면 429 응답과 오류 코드 000132가 반환됩니다. 한도 초과로 거부된 요청은 워크스페이스 한도 계산에 포함되지 않습니다. 현재 잔여 요청 한도나 사용량을 확인할 수 있는 수단(응답 헤더의 rate limit 정보, 별도 조회 API, 관리자 화면 등)은 제공되지 않습니다. 429 응답을 받으면 최소 60초 대기 후 재시도하도록 구현해 주세요. (11. 권장 연동 방식 참고)
5. 포지션 API
1) 포지션 목록 조회 API
인증된 워크스페이스의 포지션 목록을 조회합니다. 삭제된 포지션은 제외됩니다. 접수 상태와 접수 기간을 나눠 받으려면 7. 포지션 API (v2)를 사용해 주세요.
curl -G "https://api.ninehire.com/api/v1/jobs" \
-H "Authorization: Bearer ${NINEHIRE_API_KEY}" \
--data-urlencode "page=1" \
--data-urlencode "countPerPage=20" \
--data-urlencode "tags=개발" \
--data-urlencode "order=deadline_asc"
2) 요청 파라미터
필드 | 타입 | 필수여부 | 설명 | 위치 |
page | int | optional | 페이지 번호입니다. 기본값은 1입니다. | Query |
countPerPage | int | optional | 페이지당 불러올 아이템의 갯수입니다. 기본값은 10이며 최대 100개로 제한됩니다. | Query |
title | string | optional | 공고 제목 부분 일치로 검색합니다. 국문 제목과 영문 제목 모두에서 검색합니다. | Query |
tags | string[] | optional | 태그명(국문)과 정확히 일치하는 공고를 검색합니다. 여러 개 지정 시 하나라도 일치하면 포함됩니다. (예: | Query |
jobGroup | string | optional | 직군명(국문)과 정확히 일치하는 공고를 검색합니다. 직군명은 8. 직군·근무지·소속 조회 API로 확인할 수 있습니다. | Query |
employmentType | string | optional | 검색하고자 하는 공고의 고용 형태입니다. 1개만 지정할 수 있습니다. | Query |
affiliation | string | optional | 소속명(국문)과 정확히 일치하는 공고를 검색합니다. 소속명은 8. 직군·근무지·소속 조회 API로 확인할 수 있습니다. | Query |
order | string | optional | 반환되는 아이템의 정렬 방식입니다. 기본값은 최신순입니다. | Query |
language | string | optional | 언어 설정값입니다. 기본값은 한국어입니다. | Query |
includeUnpublished | boolean | optional | 보관된 포지션을 포함해 조회합니다. | Query |
includePrivate | boolean | optional | 채용 홈페이지 목록 노출이 꺼진 포지션을 포함해 조회합니다. | Query |
서로 다른 필터는 모두 AND 조건으로 함께 적용됩니다.
기본 조회에는 임시 저장·승인 대기·보관 상태를 제외한 포지션 중 채용 홈페이지 목록 노출이 켜진 포지션이 포함됩니다. 임시 저장과 승인 대기 포지션은 어떤 경우에도 목록에 포함되지 않습니다.
접수가 닫힌 포지션도 목록 노출이 켜져 있으면 기본 조회에 포함됩니다. 지원서를 받는 포지션인지는 응답의 status가 in_progress인지로 판단해 주세요.
포지션을 종료하면 채용 홈페이지 목록 노출이 자동으로 꺼집니다. 종료·보관 포지션까지 빠짐없이 조회하려면 includeUnpublished=true&includePrivate=true를 함께 지정해 주세요.
💡 적절한 쿼리를 사용하여 주세요. 포지션 목록 조회 시 쿼리를 이용하여 원하는 결과만 조회하시기를 권장드립니다.
3) 응답 예시
{
"count": 1,
"results": [
{
"id": "1a2b3c40-0000-11ef-8000-000000000001",
"title": "백엔드 개발자 (경력)",
"applyUrl": "https://example-careers.ninehire.site/job_posting/AbC12dEf",
"deadline": "2026-11-30T14:59:59.000Z",
"deadlineType": "custom_deadline",
"tags": ["개발", "서버"],
"career": "experienced",
"careerRange": { "over": 3, "below": 7 },
"employmentTypes": ["full_time"],
"jobLocations": [
{ "x": 127.0276, "y": 37.4979, "name": "서울 본사", "address": "서울 본사" }
],
"jobGroup": "개발",
"jobTask": "백엔드",
"affiliation": "플랫폼본부",
"status": "in_progress",
"isPrivate": false,
"createdAt": "2026-10-01T02:00:00.000Z"
}
]
}
4) 응답 객체(result)
키 | 타입 | 비고 | 설명 |
id | string |
| 공고별 고유한 ID 값입니다. |
title | string |
| 공고 제목(외부 노출용)입니다. |
applyUrl | string |
| 나인하이어 채용 홈페이지의 공고 페이지 URL입니다. ( |
deadline | string(datetime) | nullable | 접수 마감 일시입니다. 접수 중에는 설정된 마감 예정 일시이며, 접수를 마감(수동·예약·마감일 도래)하거나 포지션을 종료하면 처리된 시각이 기록됩니다. 마감 일시가 없으면 null이며, 상시 채용이어도 값이 있을 수 있습니다. |
deadlineType | string |
| 마감 방식입니다. |
tags | string[] |
| 공고의 태그 정보입니다. |
career | string | nullable | 공고의 경력 사항 정보입니다. |
careerRange | object | nullable | 경력 연차 범위입니다. 경력 구분이 없으면 null입니다. |
employmentTypes | string[] |
| 공고의 고용 형태 정보입니다. |
jobLocations | object[] |
| 공고의 근무지 정보입니다. |
jobGroup | string | nullable | 공고의 직군 정보입니다. |
jobTask | string | nullable | 공고의 직무 정보입니다. |
affiliation | string | nullable | 공고의 소속 정보입니다. |
createdAt | string(datetime) |
| 공고의 생성일 입니다. |
isPrivate | boolean |
| 채용 홈페이지 목록 미노출 여부입니다. 목록 노출이 꺼져 있으면 true입니다. |
status | string |
| 포지션 상태입니다. |
6. 포지션 상세 조회 API
포지션 ID로 포지션 한 건을 조회합니다. API 키 워크스페이스의 포지션만 조회되며, 삭제된 포지션은 조회되지 않습니다(404).
curl "https://api.ninehire.com/api/v1/jobs/1a2b3c40-0000-11ef-8000-000000000001?language=korean" \
-H "Authorization: Bearer ${NINEHIRE_API_KEY}"
필드 | 타입 | 필수여부 | 설명 | 위치 |
jobId | string | required | 포지션 ID입니다. 포지션 목록 조회 응답의 | Path |
language | string | optional | 언어 설정입니다. 기본값은 한국어 입니다. | Query |
1) 응답 예시
{
"id": "1a2b3c40-0000-11ef-8000-000000000001",
"title": "백엔드 개발자 (경력)",
"layoutType": "layout1",
"status": "in_progress",
"coverImageUrl": "https://(나인하이어 이미지 도메인)/job-posting/.../cover.png",
"applyUrl": "https://example-careers.ninehire.site/job_posting/AbC12dEf",
"content": "(공고 본문 HTML)",
"isActive": true,
"deadline": "2026-11-30T14:59:59.000Z",
"deadlineType": "custom_deadline",
"tags": ["개발", "서버"],
"career": "experienced",
"careerRange": { "over": 3, "below": 7 },
"employmentTypes": ["full_time"],
"jobLocations": [
{ "x": 127.0276, "y": 37.4979, "name": "서울 본사", "address": "서울 본사" }
],
"jobGroup": "개발",
"jobTask": "백엔드",
"affiliation": "플랫폼본부",
"createdAt": "2026-10-01T02:00:00.000Z",
"isPrivate": false
}
2) 응답 객체
5. 포지션 API의 응답 객체 필드 전부에 아래 필드가 추가됩니다.
키 | 타입 | 비고 | 설명 |
layoutType | string |
| 공고 레이아웃 유형입니다. |
coverImageUrl | string | nullable | 공고 커버 이미지 URL입니다. 커버 이미지가 없으면 null이며, 만료되지 않는 이미지 주소입니다. |
content | string | nullable | 공고 본문입니다. (HTML 문자열) |
isActive | boolean |
| 공고 사용(게시) 여부입니다. 포지션을 종료하거나 종료를 취소하면 자동으로 false가 됩니다. |
JobLocation
키 | 타입 | 비고 | 설명 |
x | double | nullable | 근무지 좌표 X(경도)입니다. |
y | double | nullable | 근무지 좌표 Y(위도)입니다. |
name | string |
| 근무지명 입니다. |
address | string |
| 국문 응답에서는 근무지 이름(name)과 같은 값입니다. |
7. 포지션 API (v2)
포지션 API v2는 v1의 포지션 상태(status) 하나로 표현하던 정보를 포지션 진행 상태와 접수 상태로 나눠 제공합니다. 지원서를 받는 포지션인지, 채용 홈페이지 목록에 노출되는 포지션인지 판단해야 하는 경우 v2를 사용해 주세요.
구분 | v1 | v2 |
포지션 진행 상태 |
|
|
접수 상태 |
|
|
접수 기간 |
|
|
마감 방식 |
|
|
채용 홈페이지 목록 노출 |
|
|
목록 노출이 꺼진 포지션 포함 조회 |
|
|
1) 포지션 목록 조회 API (v2)
요청 파라미터는 5. 포지션 API(v1)와 같습니다. 단, 아래 두 가지가 다릅니다.
채용 홈페이지 목록 노출이 꺼진 포지션을 포함하려면
includePrivate대신includeHidden=true를 지정해 주세요. v2에서includePrivate는 무시됩니다.order=deadline_asc의 마감일 기준은reception.endAt입니다.
종료·보관 포지션까지 빠짐없이 조회하려면 includeUnpublished=true&includeHidden=true를 함께 지정해 주세요.
응답 객체
5. 포지션 API(v1) 응답 객체에서 deadline, deadlineType, isPrivate를 제외한 필드에 아래 필드가 추가됩니다.
키 | 타입 | 비고 | 설명 |
status | string |
| 포지션 상태입니다. v1과 같은 값입니다. |
positionStatus | string | nullable | 포지션 진행 상태입니다. |
receptionStatus | string |
| 접수 상태입니다. |
reception.startAt | string(datetime) | nullable | 접수 시작 일시입니다. 접수를 바로 시작하면 시작한 시각, 시작을 예약하면 예약한 일시이며, 접수를 마감한 뒤에도 유지됩니다. |
reception.endAt | string(datetime) | nullable | 접수 마감 일시입니다. v1 deadline과 같은 값입니다. |
reception.deadlineType | string |
| 마감 방식입니다. |
reception.canSubmit | boolean |
| 지원서 제출 가능 여부입니다. status가 in_progress이면 true입니다. |
isListExposed | boolean |
| 채용 홈페이지 목록 노출 여부입니다. |
⚠️ reception.canSubmit은 포지션 상태만으로 계산됩니다. 접수 마감 일시가 지난 직후 나인하이어가 접수 마감을 처리하기 전까지는 true일 수 있으므로, 마감 시각이 중요한 처리에는 reception.endAt도 함께 확인해 주세요.
요청 예시
curl -G "https://api.ninehire.com/api/v2/jobs" \
-H "Authorization: Bearer ${NINEHIRE_API_KEY}" \
--data-urlencode "page=1" \
--data-urlencode "countPerPage=20" \
--data-urlencode "includeHidden=true"
응답 예시
{
"count": 1,
"results": [
{
"id": "1a2b3c40-0000-11ef-8000-000000000001",
"title": "백엔드 개발자 (경력)",
"applyUrl": "https://example-careers.ninehire.site/job_posting/AbC12dEf",
"tags": ["개발", "서버"],
"career": "experienced",
"careerRange": { "over": 3, "below": 7 },
"employmentTypes": ["full_time"],
"jobLocations": [
{ "x": 127.0276, "y": 37.4979, "name": "서울 본사", "address": "서울 본사" }
],
"jobGroup": "개발",
"jobTask": "백엔드",
"affiliation": "플랫폼본부",
"createdAt": "2026-10-01T02:00:00.000Z",
"status": "in_progress",
"positionStatus": "in_progress",
"receptionStatus": "open",
"reception": {
"startAt": "2026-10-01T03:00:00.000Z",
"endAt": "2026-11-30T15:00:00.000Z",
"deadlineType": "custom_deadline",
"canSubmit": true
},
"isListExposed": true
}
]
}
2) 포지션 상세 조회 API (v2)
요청 파라미터와 추가 응답 필드(layoutType, coverImageUrl, content, isActive)는 6. 포지션 상세 조회 API(v1)와 같고, 나머지 응답 필드는 1) 포지션 목록 조회 API (v2)와 같습니다.
💡 상세 조회에서는 목록에 나오지 않는 임시 저장(draft)·승인 대기(waiting_approval) 포지션도 조회되며, 이때 positionStatus는 null입니다.
curl "https://api.ninehire.com/api/v2/jobs/1a2b3c40-0000-11ef-8000-000000000001?language=korean" \
-H "Authorization: Bearer ${NINEHIRE_API_KEY}"
8. 직군·근무지·소속 조회 API
워크스페이스에 등록된 직군·근무지·소속 목록을 조회합니다. 포지션 목록 조회의 jobGroup·affiliation 필터에 넣을 값을 확인하거나, 근무지 주소를 조회할 때 사용해 주세요. 삭제된 항목은 제외됩니다.
1) 직군 목록 조회 API
직군 목록을 국문 직군명 오름차순으로 조회합니다.
요청 파라미터
필드 | 타입 | 필수여부 | 설명 | 위치 |
title | string | optional | 직군명 부분 일치로 검색합니다. (국문·영문 모두) | Query |
page | int | optional | 페이지 번호입니다. 기본값은 1입니다. | Query |
countPerPage | int | optional | 페이지당 불러올 아이템의 개수입니다. 기본값은 20입니다. | Query |
응답 객체
키 | 타입 | 비고 | 설명 |
title | string |
| 직군명(국문)입니다. 포지션 목록 조회의 |
title_english | string | nullable | 직군명(영문)입니다. |
응답 예시
{
"count": 2,
"results": [
{ "title": "개발", "title_english": "Engineering" },
{ "title": "디자인", "title_english": null }
]
}
2) 근무지 목록 조회 API
근무지 목록을 나인하이어에 설정된 근무지 표시 순서대로 조회합니다.
요청 파라미터
필드 | 타입 | 필수여부 | 설명 | 위치 |
name | string | optional | 근무지 이름 또는 주소 부분 일치로 검색합니다. (국문) | Query |
page | int | optional | 페이지 번호입니다. 기본값은 1입니다. | Query |
countPerPage | int | optional | 페이지당 불러올 아이템의 개수입니다. 기본값은 20입니다. | Query |
응답 객체
키 | 타입 | 비고 | 설명 |
x | number | nullable | 근무지 좌표 X(경도)입니다. |
y | number | nullable | 근무지 좌표 Y(위도)입니다. |
name | string |
| 근무지 이름(국문)입니다. |
name_english | string | nullable | 근무지 이름(영문)입니다. |
address | string | nullable | 근무지 주소(국문)입니다. |
응답 예시
{
"count": 1,
"results": [
{
"x": 127.0276,
"y": 37.4979,
"name": "서울 본사",
"name_english": "Seoul HQ",
"address": "서울특별시 강남구 예시로 123"
}
]
}
3) 소속 목록 조회 API
소속 목록을 나인하이어에 설정된 소속 표시 순서대로 조회합니다.
요청 파라미터
필드 | 타입 | 필수여부 | 설명 | 위치 |
title | string | optional | 소속명 부분 일치로 검색합니다. (국문·영문 모두) | Query |
page | int | optional | 페이지 번호입니다. 기본값은 1입니다. | Query |
countPerPage | int | optional | 페이지당 불러올 아이템의 개수입니다. 기본값은 20입니다. | Query |
응답 객체
키 | 타입 | 비고 | 설명 |
title | string |
| 소속명(국문)입니다. 포지션 목록 조회의 |
title_english | string | nullable | 소속명(영문)입니다. |
응답 예시
{
"count": 2,
"results": [
{ "title": "플랫폼본부", "title_english": "Platform Division" },
{ "title": "경영지원실", "title_english": null }
]
}
9. 지원자 목록 조회 API
특정 포지션의 지원자 목록을 조회합니다. 삭제된 지원자는 제외되며, 접수 일시(appliedAt) 최신순으로 정렬됩니다.
지원자 1명은 한 포지션에 대한 지원 1건을 의미합니다. 같은 사람이 여러 포지션에 지원하면 포지션마다 별도의 지원자 ID를 가집니다.
지원자 ID로 1명만 조회하는 API는 제공되지 않습니다.
응답에는 중복 지원·재지원 여부 정보가 포함되지 않습니다.
요청 파라미터
필드 | 타입 | 필수여부 | 설명 | 위치 |
jobId | string | required | 지원자의 포지션 ID입니다. | Query |
page | int | optional | 페이지 번호입니다. 기본값은 1입니다. | Query |
countPerPage | int | optional | 페이지당 반환되는 아이템의 개수입니다. 기본값은 10이며 최대 100개로 제한됩니다. | Query |
status | string[] | optional | 지원자의 상태입니다. | Query |
💡 전체 상태의 지원자를 조회하려면 status=progressing&status=passed&status=failed처럼 세 값을 모두 지정해 주세요.
최종 합격 단계에 있으면서 불합격 처리된 지원자는 passed 필터 결과에도 포함될 수 있으며, 이 경우 응답의 status 값은 failed입니다.
존재하지 않는 jobId로 조회하면 오류 없이 빈 목록(count: 0)이 반환됩니다.
요청 예시
curl -G "https://api.ninehire.com/api/v1/applicants" \
-H "Authorization: Bearer ${NINEHIRE_API_KEY}" \
--data-urlencode "jobId=1a2b3c40-0000-11ef-8000-000000000001" \
--data-urlencode "status=passed" \
--data-urlencode "countPerPage=100" \
--data-urlencode "page=1"
응답 예시
{
"count": 1,
"results": [
{
"id": "9f8e7d60-0000-11ef-9000-000000000001",
"appliedAt": "2026-10-05T03:12:45.120Z",
"updatedAt": "2026-10-20T08:00:00.000Z",
"name": "홍길동",
"email": "[email protected]",
"phoneNumber": "01000000000",
"source": "채용홈페이지",
"status": "passed",
"company": { "id": "c0ffee00-0000-11ef-8000-000000000001", "title": "예시주식회사" },
"recruitment": { "id": "1a2b3c40-0000-11ef-8000-000000000001", "title": "2026 하반기 백엔드 개발자" },
"step": { "id": "5e6f7a80-0000-11ef-8000-000000000009", "type": "passed", "title": "최종합격" },
"failReason": null,
"customAnswers": [
{
"title": "이력서",
"content": null,
"fileTitle": "홍길동_이력서",
"fileExtension": "pdf",
"fileUrl": "https://(나인하이어 파일 도메인)/...pdf?sig=...&version=v0"
}
],
"attachments": [],
"educations": [],
"experiences": [],
"licenses": [],
"languages": [],
"militaryService": null,
"veteranStatus": null,
"disability": null,
"birthday": "1995-03-15",
"gender": "man",
"integer": null,
"address": null,
"familyRelations": [],
"computerSkills": [],
"thesis": []
}
]
}
응답 객체
응답의 results 각 항목은 지원자 객체입니다. 필드 정의와 코드값, 학력·경력 등 정형 항목 예시는 지원자 데이터 정의 가이드를 참고해 주세요.
⚠️ 지원서 첨부 파일 URL(fileUrl)은 발급 시점부터 7일 후 만료됩니다. 파일을 보관해야 하면 응답을 받은 뒤 7일 안에 내려받아 주세요.
10. 지원자 등록 API
외부 채널(헤드헌터, 자체 채용 사이트, 채용 박람회 등)에서 받은 지원자를 나인하이어 포지션에 등록합니다.
요청 예시
curl -X POST "https://api.ninehire.com/api/v1/applicant" \
-H "Authorization: Bearer ${NINEHIRE_API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"jobId": "1a2b3c40-0000-11ef-8000-000000000001",
"applicant": {
"name": "김예시",
"email": "[email protected]",
"phoneNumber": "01000000000",
"applyPath": "헤드헌팅",
"appliedAt": "2026-10-20T09:00:00+09:00",
"documents": [
{ "fileUrl": "https://files.example.com/signed/resume-123.pdf?token=...", "filename": "김예시_이력서.pdf" }
]
},
"sendNotification": false
}'
요청 본문
필드 | 타입 | 필수여부 | 설명 | 파라미터 타입 |
jobId | string | required | 등록할 포지션 ID입니다. (포지션 목록 조회 응답의 id) | Body |
applicant | object | required | 등록할 지원자 정보입니다. (Applicant Object) | Body |
sendNotification | boolean | optional | 지원자에게 지원 접수 안내 메시지를 발송할지 여부입니다. 생략하면 false로 처리됩니다. | Body |
Applicant
키 | 타입 | 비고 | 설명 |
name | string | required | 지원자의 이름입니다. (30자 이내 권장) |
string | 권장 | 지원자의 이메일입니다. (이메일 형식, 200자 이내 권장) | |
phoneNumber | string | 권장 | 지원자의 연락처입니다. (숫자 형식, 30자 이내 권장) 보낸 문자열 그대로 저장됩니다. |
applyPath | string | 권장 | 지원자의 지원 경로입니다. (100자 이내 권장, 예: 헤드헌팅) 지원자 목록 조회 시 source로 반환됩니다. |
appliedAt | string | optional | 지원자의 접수일입니다. 미입력 시 요청 처리 시각으로 설정됩니다. |
documents | object[] | required | 지원자 서류 제출 정보입니다. (Document Array) |
Document
키 | 타입 | 비고 | 설명 |
fileUrl | string | required | 제출 서류의 URL입니다. 나인하이어 서버가 인증 없이 내려받을 수 있는 URL이어야 합니다. |
filename | string | required | 제출 서류의 파일명입니다. (확장자 포함, 예: 홍길동_이력서.pdf) |
💡 이름·이메일·연락처의 형식과 글자 수는 서버에서 따로 검증하지 않습니다. 위 권장값에 맞는지 연동 측에서 확인한 뒤 요청해 주세요. 요청 본문 최대 크기는 50MB입니다.
검증 규칙
대상 | 규칙 | 위반 시 |
documents[].filename | 영문 또는 숫자로 된 확장자(.pdf 등)로 끝나야 합니다. (대소문자 무시) | 422, 지원자가 등록되지 않음 |
documents | 배열이어야 합니다. (빈 배열 허용) | 누락 시 500 |
jobId | 존재하고 삭제되지 않은 포지션이어야 합니다. | 404 |
처리 방식
지원자는 대상 포지션의 첫 번째 전형 단계(일반적으로 서류 접수 단계)에 진행 중 상태로 등록됩니다.
접수 일시는
appliedAt(생략 시 요청 처리 시각)으로 기록됩니다.첨부 문서는 나인하이어 서버가
fileUrl로 인증 헤더 없이 내려받아 저장합니다. 만료 시간이 충분한 서명 URL 등, 요청 시점에 인증 없이 내려받을 수 있는 URL을 사용해 주세요.저장된 파일은 지원서의 첨부 항목으로 들어가며, 항목 제목은
filename에서 확장자를 뺀 값입니다. 확장자가 pdf이면 문서 파일 항목, 그 외에는 일반 파일 항목으로 저장되며, 지원자 목록 조회 시customAnswers에 포함됩니다.파일을 내려받지 못한 항목은 오류 없이 건너뛰고, 나머지 정보로 지원자 등록을 완료합니다. 첨부가 중요한 경우 등록 후 지원자 목록 조회로 첨부 반영 여부를 확인해 주세요.
sendNotification이 true이면 지원자에게 지원 접수 안내 메시지가 발송됩니다. 포지션에 접수 안내 메시지 템플릿이 설정되어 있으면 그 내용으로, 없으면 나인하이어 기본 문구로 발송됩니다.지원자 개인정보의 파기 예정일은 접수 일시와 워크스페이스의 개인정보 보유 기간 설정으로 계산되며, 개인정보 수집 동의 이력은 미동의 상태로 저장됩니다.
⚠️ 이메일·전화번호 등으로 기존 지원자와 중복 여부를 확인하지 않습니다. 같은 요청을 두 번 보내면 지원자가 두 명 등록되므로, 네트워크 오류 등으로 재시도할 때는 먼저 지원자 목록 조회로 등록 여부를 확인한 뒤 다시 요청해 주세요.
응답
201 Created이며 본문이 없습니다. 등록된 지원자 ID는 응답으로 반환되지 않으므로, 지원자 ID가 필요하면 지원자 목록 조회 API로 조회해 주세요. 접수 최신순으로 정렬되므로 방금 등록한 지원자가 앞쪽에 있습니다. 단, appliedAt을 과거 시각으로 지정하면 그 시각 기준으로 정렬됩니다.
11. 권장 연동 방식
1) 대량 조회
목록 조회는
countPerPage=100으로 페이지를 순회해 호출 횟수를 줄여 주세요.워크스페이스 한도(60초 60회)를 넘지 않도록 요청 간격을 1초 이상 두거나, 분당 호출 수를 직접 제한해 주세요.
지원자 목록은 접수 최신순이므로, 신규 지원자를 수집할 때는 1페이지부터 조회하다가 이미 수집한 지원자 ID가 나오면 중단하는 방식으로 호출 수를 줄일 수 있습니다.
페이지 순회 중 데이터가 바뀌면 항목이 중복되거나 누락될 수 있습니다. ID 기준으로 중복을 제거하고, 주기적으로 전체를 다시 동기화해 누락을 보완해 주세요.
포지션 전체를 수집하려면
includeUnpublished=true&includePrivate=true(v2는includeHidden=true)를 함께 지정해 주세요.
2) 요청 한도 초과(429) 대응
429응답을 받으면 최소 60초 대기 후 재시도해 주세요. 대기 시간을 늘려 가며 재시도하는 방식(예: 60초 → 120초 → 240초)과 최대 재시도 횟수 지정을 권장합니다.한도 정보를 알려주는 응답 헤더가 없으므로, 직전 60초 동안의 호출 수를 연동 측에서 직접 집계해 주세요.
여러 서버·배치가 같은 API 키를 사용한다면 호출 수를 한곳에서 통제해 주세요.
3) 오류 처리
HTTP | 권장 처리 |
400, 422 | 요청 값을 수정한 뒤 다시 요청 (같은 요청으로 재시도하지 않음) |
401 | API 키 값과 헤더 형식 확인 (재시도하지 않음) |
404 (등록된 키 없음) | API 키가 삭제·교체된 상태이므로 새 키로 설정 교체 |
404 (그 외) | 대상 ID 확인 |
429 | 대기 후 재시도 |
500 | 잠시 후 제한적으로 재시도. 지원자 등록 API는 재시도 전 등록 여부를 먼저 확인 |
4) 첨부 파일 보관
지원서 첨부 파일 URL(
fileUrl)은 발급 시점부터 7일 후 만료됩니다. 이력서·포트폴리오 등을 고객사 시스템에 보관해야 하면 응답·웹훅을 받은 직후(늦어도 7일 이내) 내려받아 자체 저장소에 저장해 주세요.만료된 경우 지원자 목록 조회를 다시 호출해 새 URL을 받아 주세요.
파일명은
fileTitle+.+fileExtension으로 구성할 수 있습니다.
5) 지원자 등록
등록 전 포지션 목록 조회로 대상 포지션 ID를 확인해 주세요.
documents[].fileUrl은 나인하이어 서버가 요청을 처리하는 동안 인증 없이 내려받을 수 있어야 합니다. 서명 URL을 쓴다면 만료 시간을 충분히(예: 10분 이상) 두어 주세요.요청 기록, 재시도 전 조회 등 중복 등록 방지 로직을 연동 측에 구현해 주세요.
지원 접수 안내 메시지를 고객사에서 따로 발송한다면
sendNotification: false로 보내 주세요.
6) v2 활용
지원서를 받는 포지션인지 판단해야 하면 v1의
status·deadline조합 대신 v2의receptionStatus또는reception.canSubmit을 사용해 주세요.채용 홈페이지 목록 노출 여부는 v2
isListExposed로 판단하고, 목록 노출이 꺼진 포지션까지 조회할 때는includeHidden=true를 지정해 주세요.접수 기간이 설정되지 않은 포지션을 구분해야 하면 v2
reception.deadlineType의none을 사용해 주세요. v1은open_ended로 표시되어 상시 채용과 구분되지 않습니다.v2는 포지션 조회만 제공합니다. 직군·근무지·소속 조회와 지원자 조회·등록은 v1을 사용하며, 웹훅 본문도 v1 형식입니다.

