PARKING 24 파트너 API 문서
파트너 API는 PARKING 24와 협약된 파트너사가 자사 서비스에서 주차 예약을 생성하고 관리할 수 있도록 제공하는 HTTP API입니다.
Quickstart — 5분 첫 호출
API 키 발급부터 첫 검색 응답까지 5분 안에 검증하는 절차입니다.
1. Sandbox 키 발급 (1분)
파킹24 파트너스 /partner/api-keys 에서 Sandbox 토글 ON 으로 새 키 생성. 키 prefix 가 pk24_test_ 인지 확인. 생성 직후 1회만 plain key가 표시되므로 즉시 저장합니다.
파트너 포털 계정이 아직 없으면 "통합 문의 / 연락처" 섹션 참조 — 담당자에게 계정 + 키 발급 요청.
2. 인증 헤더 + 첫 검색 (2분)
KST 기준 미래 날짜 + 공항 UUID 로 검색합니다. 공항 UUID 는 /partner/api-guide Playground 의 "공항 chip" 에 표시됩니다.
curl -sS "https://parking24.me/api/partner-api/v1/search\
?airport_id=YOUR_AIRPORT_UUID\
&checkin_date=2026-06-01\
&checkout_date=2026-06-03" \
-H "Authorization: Bearer pk24_test_YOUR_TEST_KEY"성공 응답 예시 — plans[] 가 채워져 있으면 인증/공항 매칭 모두 OK 입니다.
{
"success": true,
"data": {
"plans": [
{
"plan_id": "550e8400-e29b-41d4-a716-446655440000",
"plan_name": "Standard",
"original_price": 60000,
"discounted_price": 54000,
"available_quantity": null,
"services": [],
"ev_restricted": false
}
],
"total_days": 3,
"surcharges": null
},
"error": null
}실패 시 error_code 값을 보고 분기:
AUTH_REQUIRED/INVALID_API_KEY→ 헤더/키 확인AIRPORT_NOT_AVAILABLE→ 공항 UUID 확인 또는 파트너 visible_airport_ids 권한 확인INVALID_DATE→ KST 미래 날짜 +YYYY-MM-DD형식 확인
3. 다음 단계 (2분)
위 검색이 성공하면 같은 키로 예약 생성 (POST /reservations) → 조회 (GET /reservations) → 취소 (PATCH /reservations) 순으로 검증합니다. 각 엔드포인트 상세는 본문 아래 섹션 참조. 통합 검증이 끝나면 "통합 문의 / 연락처" 로 Live 키 발급 요청.
🧪 Sandbox 예약은 실 정산·매출에서 자동 제외됩니다. 코드 변경 없이 키 prefix 만
pk24_live_로 교체하면 Live 전환 완료.
Base URL & 버전
- Base URL:
https://parking24.me - 권장 prefix:
/api/partner-api/v1/...(예:https://parking24.me/api/partner-api/v1/reservations) - 무버전 경로
/api/partner-api/...도 현재 동일 동작하지만 2026-11-14 이후 deprecation 예정(6개월 윈도우). 신규 통합은 반드시/v1/사용. - 응답 형식·인증·rate limit·헤더 모두 동일. 라우팅 alias만 차이.
OpenAPI / Postman
자동화 친화 — OpenAPI 3.0 spec 을 그대로 import 해서 클라이언트 SDK / Postman collection 을 자동 생성할 수 있습니다.
- OpenAPI 3.0 yaml:
https://parking24.me/docs/partner-api/openapi.yaml(무인증 공개, 1시간 캐시) - Postman 에서 import: File → Import → Link → 위 URL 붙여넣기 → Continue
OpenAPI Generator / Swagger Codegen 등과 호환됩니다 (/v1/ prefix 의 server 가 default).
인증
모든 요청에 아래 헤더를 포함해야 합니다.
# Live (운영)
Authorization: Bearer pk24_live_<YOUR_LIVE_KEY>
# Sandbox (테스트) — 통합 검증용. 정산·매출 집계에서 자동 제외.
Authorization: Bearer pk24_test_<YOUR_TEST_KEY>
- API 키는 파킹24 파트너스 (
https://parking24.me/partner/api-keys) 에서 발급합니다. - 키 prefix 가 환경을 결정합니다. 자세한 내용은 "Sandbox & Live 환경" 섹션 참조.
- 키 노출 시 즉시 어드민 담당자에게 재발급을 요청하세요.
Sandbox & Live 환경
파트너 API 는 Sandbox (테스트) 와 Live (운영) 두 환경을 같은 베이스 URL 로 제공합니다. 환경은 API 키 prefix 로 결정됩니다 — 코드 분기 불필요, 키만 교체.
키 prefix
| 환경 | Prefix | 설명 |
|---|---|---|
| Live | pk24_live_ | 운영. 모든 예약이 실 매출·정산에 반영됩니다. |
| Sandbox | pk24_test_ | 테스트. 예약은 만들어지지만 정산·매출 집계에서 제외됩니다. |
키 발급
파킹24 파트너스 https://parking24.me/partner/api-keys 에서:
- "새 API 키" 버튼 → 키 이름 입력
- Sandbox 토글 선택 (운영 키는 OFF, 테스트 키는 ON)
- 생성 직후 1회만 plain key 표시 — 안전한 곳에 저장 필수
- 키 목록에
TEST/LIVE배지로 환경 구분
Sandbox 예약 동작
Sandbox 키로 만든 예약은 실 예약 시스템 동작과 완전 동일합니다. 다음 차이만 있습니다:
| 항목 | Live | Sandbox |
|---|---|---|
| 예약 생성 응답 | 정상 | 정상 (실 row 생성) |
reservations.is_sandbox | false | true |
| 매출/커미션 집계 | 반영 | 제외 |
| 정산 PDF | 매출 포함 | 매출 제외 (0건 표시 가능) |
| Webhook 발송 | 정상 | 정상 |
| Webhook payload | is_sandbox: false | is_sandbox: true |
| 쿠폰 분담 정산 | 반영 | 제외 |
| Rate limit | 키별 동일 | 키별 동일 |
⚠️ Sandbox 예약은 실제 주차 서비스가 제공되지 않습니다. 차량번호·연락처·이름은 테스트 더미 값을 사용하세요.
Webhook payload 분기
수신 측에서 sandbox 이벤트를 분리 처리하려면 data.is_sandbox 필드를 확인:
app.post('/webhook', (req, res) => {
const { event, data } = req.body;
if (data.is_sandbox) {
// 테스트 트래픽 — staging DB 저장 또는 무시
console.log('sandbox event:', event);
return res.status(200).end();
}
// live 트래픽 처리
});권장 통합 단계
- Sandbox 키 발급 — 파킹24 파트너스에서 sandbox 토글로 발급
- 로컬/staging 통합 — 모든 시나리오 검증
- 검색 → 예약 생성 → 조회 → 취소
- 쿠폰 검증 → 적용
- Webhook 수신 + 서명 검증
- 에러 코드별 분기 (
error_codeenum)
- Webhook URL 등록 — sandbox endpoint 또는 logging-only endpoint 로 설정
- Live 키 발급 요청 — PARKING 24 어드민 담당자에게 운영 키 발급 요청 (수동 승인)
- Live 전환 — 환경 변수만 교체 (
pk24_test_*→pk24_live_*). 코드 변경 없음
주의사항
- 데이터 격리는 키 단위가 아닌
partner_id단위: 같은 파트너의 sandbox 키 / live 키 는 같은partner_id를 공유합니다. 다른 파트너의 예약은 어느 키로도 조회 불가. - 실 사용자 데이터 금지: sandbox 예약에 실 차량번호/연락처/이메일 사용 금지. 마케팅·결제 시스템과 분리되지 않는 데이터.
- 혼용 금지: 같은 서비스 인스턴스에서 sandbox/live 키 혼용 시 정산 혼선 위험. 환경 변수로 강제 분리 권장 (예:
PARKING24_API_KEY단일 ENV + 환경별 배포). - 키 폐기는 영구적: sandbox 키도 한번 폐기하면 복구 불가. 발급·폐기는 파트너 포털 UI 에서 직접 관리.
공통 응답 형식
모든 응답은 아래 JSON 구조를 따릅니다.
{
"success": true,
"data": { ... },
"error": null
}| 필드 | 타입 | 설명 |
|---|---|---|
success | boolean | 요청 성공 여부 |
data | object | null | 성공 시 응답 데이터, 실패 시 null |
error | string | null | 실패 시 오류 메시지, 성공 시 null |
공통 규약 (timezone / currency / Idempotency)
Timezone
- 모든 날짜(
checkin_date,checkout_date등YYYY-MM-DD형식)는 한국 표준시(Asia/Seoul, UTC+09:00) 기준입니다. 시차 변환은 제휴사 측에서 처리하지 않아도 됩니다. - 모든 시각(
checkin_time,checkout_time등HH:MM형식) 역시 KST 기준입니다. - 모든 타임스탬프(
created_at,updated_at,expires_at, webhooktimestamp등)는 ISO 8601 UTC 형식으로 반환됩니다. 엔드포인트별로Zsuffix(2026-03-10T01:00:00.000Z) 또는+00:00offset(2026-03-10T01:00:00.000+00:00)이 사용되며 둘은 동일한 UTC 시각을 의미합니다 (표준 ISO 8601 파서로 모두 처리 가능). UTC를 KST로 변환하려면 +9시간 적용.
Currency
- 모든 금액 필드(
original_price,discounted_price,total_price,cancellation_fee,discount_amount,parking24_cost,partner_cost,final_price등)는 대한민국 원(KRW) 단위의 정수입니다. 소수점·통화기호·자릿수 구분자 없이 정수로만 반환됩니다. - 모든 통화는 KRW로 고정되며 별도
currency필드는 응답에 포함되지 않습니다.
Idempotency-Key (재시도 안전성)
mutation 엔드포인트(POST /reservations, PATCH /reservations, POST /coupon/apply)에 Idempotency-Key 헤더를 함께 보내면 동일 키로 24시간 내 재호출 시 첫 응답이 그대로 재생됩니다. 네트워크 오류·timeout 후 안전한 재시도 보장.
Idempotency-Key: 8f3b9c2a-1d2e-4f5a-b6c7-d8e9f0a1b2c3
| 시나리오 | 동작 |
|---|---|
| 헤더 미사용 | 매 호출마다 새 mutation 수행 (기존 동작) |
| 같은 키 + 같은 body 재호출 | 첫 응답 status·body 그대로 반환 |
| 같은 키 + 다른 body | 422 Unprocessable Entity |
| 같은 키 동시 호출 | 409 Conflict ("이전 요청 처리 중") |
| 24시간 경과 후 동일 키 | 만료된 레코드 삭제 후 새 mutation 수행 |
| 첫 호출이 5xx로 실패 | 5분 후 동일 키 재시도 가능 |
권장: 클라이언트에서 UUID v4를 생성하여 사용. 키 길이 1~255자. 같은 키를 다른 사용자 데이터(예: 다른 차량번호)로 재사용하지 마세요 — 422가 반환됩니다.
응답 헤더 X-P24-Timing (디버깅·SLO)
모든 partner-api 응답에는 단계별 처리 시간을 담은 X-P24-Timing 헤더가 포함됩니다. 형식은 W3C Server-Timing 사양을 따르되 헤더 이름만 커스텀(X- prefix)을 사용합니다.
X-P24-Timing: auth;dur=22.7, idem-lookup;dur=0.0, main-batch;dur=34.9, insert;dur=25.3, create;dur=60.4, total;dur=84.0
각 name;dur=ms 토큰의 의미:
| 단계 | 설명 |
|---|---|
auth | API 키 검증 + rate-limit + partner 활성/IP 검증 |
idem-lookup | Idempotency-Key 헤더 사용 시 lookup (헤더 미사용이면 0) |
main-batch | 예약 생성 시 가격·공항·이용권·중복 검증 등 병렬 쿼리 배치 |
insert | reservations INSERT (POST에만 노출) |
create | POST 핸들러 내부 mutation 총합 (main-batch + insert + 기타) |
total | 서버 측 처리 시간 총합 (네트워크 RTT 미포함) |
용도:
- 클라이언트측 SLO 모니터링 — 평균/p95 latency를 자체 대시보드로 추적
- 디버깅 — 응답이 느릴 때 어느 단계가 병목인지 즉시 확인
- 외부 제휴사 자동화 — 측정값을 외부 알람(Datadog, PagerDuty 등)에 연결 가능
참고: Vercel runtime이 표준 Server-Timing 헤더를 자체 처리/덮어쓰는 동작이 있어 커스텀 X-P24-Timing을 사용합니다. 값 형식은 표준과 동일하므로 동일 파서로 처리 가능합니다.
에러 코드
| HTTP 상태 코드 | 설명 |
|---|---|
400 Bad Request | 필수 파라미터 누락, 잘못된 날짜 형식, 논리적으로 유효하지 않은 입력(예: 체크아웃 날짜가 체크인 날짜보다 이전), 현재 상태에서 취소 불가 |
401 Unauthorized | Authorization 헤더 누락 또는 유효하지 않은 API 키 |
403 Forbidden | API 키는 유효하나 해당 리소스에 대한 접근 권한 없음 |
404 Not Found | 요청한 예약 정보를 찾을 수 없음 |
409 Conflict | 동일 차량이 같은 기간에 이미 예약이 존재함, 또는 같은 Idempotency-Key 가 처리 중 |
422 Unprocessable Entity | 같은 Idempotency-Key 로 다른 body 재호출 (요청 본문이 처음 호출과 불일치) |
429 Too Many Requests | Rate Limit 초과. Retry-After 헤더에 재시도 대기 시간(초)이 포함됨 |
실패 응답 예시:
{
"success": false,
"data": null,
"error": "airport_id, checkin_date, checkout_date are required",
"error_code": "MISSING_FIELD"
}error_code enum (자동화 분기용)
응답 body에 error_code 필드가 함께 반환됩니다. 사람 가독 error 메시지는 시간이 지나면서 변경될 수 있지만 error_code는 stable합니다. 외부 제휴사 자동화에서 분기/알람용으로 사용하세요.
error_code | 일반 HTTP | 설명 |
|---|---|---|
AUTH_REQUIRED | 401 | Authorization 헤더 누락 |
INVALID_API_KEY | 401 | API 키 형식·존재 모두 무효 |
API_KEY_REVOKED | 401 | 폐기된 API 키 |
API_KEY_EXPIRED | 401 | 만료된 API 키 |
PARTNER_INACTIVE | 403 | 비활성 파트너 |
IP_NOT_ALLOWED | 403 | IP allowlist 위반 |
RATE_LIMITED | 429 | 분당 요청 한도 초과 (Retry-After 헤더 참조) |
MISSING_FIELD | 400 | 필수 파라미터 누락 |
INVALID_FIELD | 400 | 일반 유효성 실패 |
INVALID_UUID | 400 | UUID 형식 오류 |
INVALID_DATE | 400 | 날짜 형식·범위 오류 |
INVALID_TIME | 400 | 시간 형식 오류 |
FIELD_TOO_LONG | 400 | 문자열 길이 초과 |
MAX_DURATION_EXCEEDED | 400 | 예약 기간 365일 초과 |
PLAN_NOT_FOUND | 400 | 이용권 가격 정보 없음 |
EV_NOT_ALLOWED | 400 | 전기차 + EV 제한 plan |
AIRPORT_NOT_AVAILABLE | 400 | 파트너 visible airport 위반 또는 공항 미존재 |
PLAN_NOT_AVAILABLE | 400 | 파트너 visible plan 위반 |
EXCLUSIVE_SOLD_OUT | 400 | Exclusive 이용권 매진 |
EXCLUSIVE_ACCESS_DENIED | 403 | 전용주차장 접근 권한 없음 |
RESERVATION_DUPLICATE | 409 | 동일 차량 같은 기간 중복 |
RESERVATION_NOT_FOUND | 404 | 예약 미존재 (PATCH/쿠폰 적용) |
RESERVATION_ALREADY_CANCELLED | 400 | 이미 취소된 예약 |
RESERVATION_NOT_CANCELLABLE | 400 | 현재 상태에서 취소 불가 |
IDEMPOTENCY_KEY_INVALID | 400 | Idempotency-Key 형식 오류 (1~255자) |
IDEMPOTENCY_KEY_IN_PROGRESS | 409 | 동일 키 이전 요청 처리 중 |
IDEMPOTENCY_BODY_MISMATCH | 422 | 동일 키 다른 body |
COUPON_INVALID | 400 | 유효하지 않은 쿠폰 |
COUPON_ALREADY_APPLIED | 400 | 예약에 쿠폰 중복 적용 시도 |
INTERNAL_ERROR | 500 | 서버 내부 오류 |
기존 error 텍스트 필드는 호환을 위해 유지되며 로깅·UI 표시용으로 활용 가능합니다.
엔드포인트
1. 주차 이용권 검색
특정 공항과 날짜 범위에서 예약 가능한 이용권 목록과 파트너 적용 가격을 반환합니다.
GET /api/partner-api/search
쿼리 파라미터
| 파라미터 | 타입 | 필수 | 설명 |
|---|---|---|---|
airport_id | string (UUID) | ✅ | 공항 UUID |
checkin_date | string | ✅ | 입차 날짜 (형식: YYYY-MM-DD) |
checkout_date | string | ✅ | 출차 날짜 (형식: YYYY-MM-DD, 입차 날짜 이후여야 함) |
응답 (200 OK)
{
"success": true,
"data": {
"plans": [
{
"plan_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"plan_name": "Standard",
"original_price": 75000,
"discounted_price": 67500,
"available_quantity": null,
"services": ["실외 주차", "기본 보관"],
"ev_restricted": false
},
{
"plan_id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
"plan_name": "Exclusive",
"original_price": 200000,
"discounted_price": 180000,
"available_quantity": 5,
"services": ["전용 구역", "프리미엄 세차", "차량 정비", "보험", "라운지 이용권"],
"ev_restricted": false
}
],
"total_days": 5,
"surcharges": {
"T1": { "base_surcharge": 5000, "night_surcharge": 3000, "night_start": 19, "night_end": 5 },
"T2": { "base_surcharge": 7000, "night_surcharge": 3000, "night_start": 19, "night_end": 5 }
}
},
"error": null
}응답 필드 설명 (data)
| 필드 | 타입 | 설명 |
|---|---|---|
plans | array | 이용권 배열 (아래 필드 참조) |
total_days | number | 입차~출차 양쪽 포함 일수 |
surcharges | object | null | 해당 공항의 터미널별 추가요금 설정 ({ T1: { base_surcharge, night_surcharge, night_start, night_end }, T2: {...} }). 예약 생성 시 terminal 필드와 함께 사용 |
plans[*] 필드
| 필드 | 타입 | 설명 |
|---|---|---|
plan_id | string (UUID) | 이용권 ID (예약 생성 시 사용) |
plan_name | string | 이용권 이름 |
original_price | number | 검색 기간 전체 정상가 합계 (원) |
discounted_price | number | 파트너 할인 적용 후 합계 가격 (원) |
available_quantity | number | null | Exclusive 플랜의 잔여 수량, 일반 플랜은 null |
services | array | 이용권 포함 서비스 목록 |
ev_restricted | boolean | 전기차 이용 제한 여부 (실내주차장 등) |
curl 예시
curl -X GET \
"https://parking24.me/api/partner-api/search?airport_id=a1b2c3d4-e5f6-7890-abcd-ef1234567890&checkin_date=2026-03-10&checkout_date=2026-03-15" \
-H "Authorization: Bearer pk24_live_your_api_key_here"2. 예약 생성
지정한 이용권으로 새 예약을 생성합니다. 생성된 예약은 booking_source: PARTNER_API로 기록됩니다. booking_source는 서버에서 자동 생성되는 읽기 전용 필드이며, 요청 시 전송할 필요가 없습니다.
POST /api/partner-api/reservations
요청 Body (application/json)
{
"airport_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"plan_id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
"checkin_date": "2026-03-10",
"checkout_date": "2026-03-15",
"checkin_time": "10:00",
"checkout_time": "18:00",
"terminal": "T1",
"customer_name": "홍길동",
"customer_phone": "010-1234-5678",
"car_number": "12가3456",
"is_electric_vehicle": false,
"memo": "트렁크에 짐 있음"
}요청 필드 설명
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
airport_id | string (UUID) | ✅ | 공항 UUID |
plan_id | string (UUID) | ✅ | 이용권 UUID (검색 API의 plan_id) |
exclusive_lot_id | string (UUID) | ❌ | 전용주차장 UUID (Exclusive 이용권 예약 시 사용) |
checkin_date | string | ✅ | 입차 날짜 (형식: YYYY-MM-DD) |
checkout_date | string | ✅ | 출차 날짜 (형식: YYYY-MM-DD, 입차 날짜 이후여야 함, 최대 365일) |
checkin_time | string | ❌ | 입차 시간 (형식: HH:MM, 기본값: 10:00) |
checkout_time | string | ❌ | 출차 시간 (형식: HH:MM, 기본값: 18:00) |
terminal | string | ❌ | 터미널 코드 (예: T1, T2). 검색 API 응답의 surcharges 키와 일치해야 하며, 미지정 시 터미널 추가요금 미적용 |
customer_name | string | ✅ | 예약자 이름 (최대 100자) |
customer_phone | string | ✅ | 예약자 연락처 (최대 20자) |
car_number | string | ✅ | 차량 번호 (최대 20자) |
is_electric_vehicle | boolean | ❌ | 전기차 여부. true이고 이용권의 ev_restricted=true인 경우 400 반환 |
memo | string | ❌ | 전달 메모 (최대 500자) |
응답 (201 Created)
{
"success": true,
"data": {
"reservation_number": "PK20260310001",
"status": "CONFIRMED",
"checkin_date": "2026-03-10",
"checkin_time": "10:00",
"checkout_date": "2026-03-15",
"checkout_time": "18:00",
"total_price": 180000,
"plan_name": "Exclusive",
"customer_name": "홍길동",
"car_number": "12가3456",
"memo": "트렁크에 짐 있음"
},
"error": null
}응답 필드 설명
| 필드 | 타입 | 설명 |
|---|---|---|
reservation_number | string | 예약 번호 (조회 및 취소 시 사용) |
status | string | 예약 상태 (CONFIRMED) |
checkin_date | string | 입차 날짜 |
checkin_time | string | 입차 시간 |
checkout_date | string | 출차 날짜 |
checkout_time | string | 출차 시간 |
total_price | number | 최종 결제 금액 (원) |
plan_name | string | 예약된 이용권 이름 |
customer_name | string | 예약자 이름 |
car_number | string | 차량 번호 |
memo | string | null | 전달 메모 |
curl 예시
curl -X POST \
"https://parking24.me/api/partner-api/reservations" \
-H "Authorization: Bearer pk24_live_your_api_key_here" \
-H "Content-Type: application/json" \
-d '{
"airport_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"plan_id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
"checkin_date": "2026-03-10",
"checkout_date": "2026-03-15",
"checkin_time": "10:00",
"checkout_time": "18:00",
"customer_name": "홍길동",
"customer_phone": "010-1234-5678",
"car_number": "12가3456",
"memo": "트렁크에 짐 있음"
}'3. 예약 조회
파트너가 생성한 예약 목록을 조회합니다. 예약 번호나 상태로 필터링하거나 페이지네이션을 사용할 수 있습니다.
GET /api/partner-api/reservations
쿼리 파라미터
| 파라미터 | 타입 | 필수 | 기본값 | 설명 |
|---|---|---|---|---|
reservation_number | string | ❌ | — | 특정 예약 번호로 단건 조회 |
status | string | ❌ | — | 예약 상태 필터 (CONFIRMED, CHECKED_IN, CANCELLED 등) |
page | number | ❌ | 1 | 페이지 번호 (1부터 시작) |
limit | number | ❌ | 20 | 페이지당 건수 (최대 100) |
응답 (200 OK)
{
"success": true,
"data": {
"reservations": [
{
"id": "f1e2d3c4-b5a6-7890-fedc-ba9876543210",
"reservation_number": "PK20260310001",
"airport_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"plan_id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
"exclusive_lot_id": null,
"customer_name": "홍길동",
"car_number": "12가3456",
"checkin_date": "2026-03-10",
"checkin_time": "10:00",
"checkout_date": "2026-03-15",
"checkout_time": "18:00",
"terminal": "T1",
"memo": "트렁크에 짐 있음",
"total_days": 5,
"price_per_day": 36000,
"partner_discount_amount": 18000,
"total_price": 180000,
"cancellation_fee": 0,
"status": "CONFIRMED",
"booking_source": "PARTNER_API",
"created_at": "2026-02-24T10:00:00.000Z",
"updated_at": "2026-02-24T10:00:00.000Z"
}
],
"total": 1,
"page": 1,
"limit": 20
},
"error": null
}응답 필드 설명 (data)
| 필드 | 타입 | 설명 |
|---|---|---|
reservations | array | 예약 레코드 배열 |
total | number | 필터 조건에 해당하는 전체 예약 건수 |
page | number | 현재 페이지 번호 |
limit | number | 페이지당 건수 |
예약 레코드 필드 (reservations[*])
| 필드 | 타입 | 설명 |
|---|---|---|
id | string (UUID) | 예약 고유 ID |
reservation_number | string | 예약 번호 |
airport_id | string (UUID) | 공항 UUID |
plan_id | string (UUID) | 이용권 UUID |
exclusive_lot_id | string (UUID) | null | 전용주차장 UUID (해당 시) |
customer_name | string | 예약자 이름 |
car_number | string | 차량 번호 |
checkin_date | string | 입차 날짜 |
checkin_time | string | 입차 시간 |
checkout_date | string | 출차 날짜 |
checkout_time | string | 출차 시간 |
terminal | string | null | 터미널 코드 |
memo | string | null | 전달 메모 |
total_days | number | 예약 일수 (양쪽 포함) |
price_per_day | number | 저장 시점 1일 단가 (원) |
partner_discount_amount | number | 파트너 할인 적용액 (원) |
total_price | number | 최종 결제 금액 (원, 추가요금 포함) |
cancellation_fee | number | 적용된 취소 수수료 (원) |
status | string | 예약 상태 |
booking_source | string | 예약 출처 (PARTNER_API) |
created_at | string | 예약 생성 일시 (ISO 8601) |
updated_at | string | 마지막 수정 일시 (ISO 8601) |
curl 예시
전체 목록 조회:
curl -X GET \
"https://parking24.me/api/partner-api/reservations?page=1&limit=20" \
-H "Authorization: Bearer pk24_live_your_api_key_here"특정 예약 단건 조회:
curl -X GET \
"https://parking24.me/api/partner-api/reservations?reservation_number=PK20260310001" \
-H "Authorization: Bearer pk24_live_your_api_key_here"상태별 필터 조회:
curl -X GET \
"https://parking24.me/api/partner-api/reservations?status=CONFIRMED&page=1&limit=20" \
-H "Authorization: Bearer pk24_live_your_api_key_here"4. 예약 취소
생성된 예약을 취소합니다. CONFIRMED 또는 CHECKED_IN 상태의 예약만 취소할 수 있습니다.
PATCH /api/partner-api/reservations
요청 Body (application/json)
{
"reservation_number": "PK20260310001"
}요청 필드 설명
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
reservation_number | string | ✅ | 취소할 예약 번호 |
응답 (200 OK)
{
"success": true,
"data": {
"reservation_id": "f1e2d3c4-b5a6-7890-fedc-ba9876543210",
"reservation_number": "PK20260310001",
"status": "CANCELLED",
"cancellation_fee": 5000,
"total_price": 60000,
"refund_amount": 55000
},
"error": null
}응답 필드 설명
| 필드 | 타입 | 설명 |
|---|---|---|
reservation_id | string (UUID) | 취소된 예약의 UUID |
reservation_number | string | 취소 처리된 예약 번호 |
status | string | 변경된 예약 상태 (CANCELLED) |
cancellation_fee | integer (KRW) | 적용된 취소 수수료. site_settings.cancellation_fee_hours 이내 취소 시 cancellation_fee_amount 부과, 그 외 0 |
total_price | integer (KRW) | 원 결제 총액 |
refund_amount | integer (KRW) | 환불 예정 금액 = total_price − cancellation_fee (0 미만 cap) |
취소 불가 조건
아래 상태의 예약은 취소할 수 없으며 400 에러를 반환합니다.
CANCELLED— 이미 취소된 예약COMPLETED— 출차 완료된 예약
curl 예시
curl -X PATCH \
"https://parking24.me/api/partner-api/reservations" \
-H "Authorization: Bearer pk24_live_your_api_key_here" \
-H "Content-Type: application/json" \
-d '{
"reservation_number": "PK20260310001"
}'예약 상태 흐름
CONFIRMED → CHECKED_IN → COMPLETED
↓ ↓
CANCELLED CANCELLED
| 상태 | 설명 |
|---|---|
CONFIRMED | 예약 완료 (취소 가능) |
CHECKED_IN | 차량 입차 완료 (취소 가능) |
COMPLETED | 출차 완료 (취소 불가) |
CANCELLED | 취소됨 |
5. 쿠폰 검증
쿠폰 코드의 유효성을 검증하고 적용 후 금액을 계산하여 반환합니다. 검색 결과의 discounted_price를 original_price로 넘기는 것을 권장합니다.
POST /api/partner-api/coupon/validate
요청 Body (application/json)
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
code | string | ✅ | 검증할 쿠폰 코드 |
original_price | number | ✅ | 할인 적용 전 가격 (원, 0 이상). 보통 검색 API의 discounted_price 사용 |
응답 (200 OK)
{
"success": true,
"data": {
"valid": true,
"coupon_id": "c1d2e3f4-a5b6-7890-cdef-123456789012",
"coupon_code_id": "d2e3f4a5-b6c7-8901-defa-234567890123",
"discount_amount": 18000,
"parking24_cost": 12600,
"partner_cost": 5400,
"final_price": 162000
},
"error": null
}응답 필드 설명
| 필드 | 타입 | 설명 |
|---|---|---|
valid | boolean | 유효 여부 (성공 시 true) |
coupon_id | string (UUID) | null | 쿠폰 마스터 ID |
coupon_code_id | string (UUID) | null | 1회용 코드인 경우 코드 레코드 ID |
discount_amount | number | 적용 가능한 할인액 (원) |
parking24_cost | number | PARKING 24가 부담하는 분담액 (원) |
partner_cost | number | 파트너가 부담하는 분담액 (원, 정산 시 차감) |
final_price | number | 할인 적용 후 최종 가격 (원) |
무효 쿠폰은 success: false + error 메시지(예: "쿠폰이 만료되었습니다")로 400을 반환합니다.
curl 예시
curl -X POST \
"https://parking24.me/api/partner-api/coupon/validate" \
-H "Authorization: Bearer pk24_live_your_api_key_here" \
-H "Content-Type: application/json" \
-d '{"code": "SUMMER2026", "original_price": 180000}'6. 쿠폰 적용
예약에 쿠폰 할인을 적용합니다. 예약 1건당 쿠폰 1개만 적용 가능합니다. 적용 시 파트너 분담액은 settlement_adjustments에 자동 기록됩니다.
POST /api/partner-api/coupon/apply
요청 Body (application/json)
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
code | string | ✅ | 적용할 쿠폰 코드 |
reservation_id | string (UUID) | ✅ | 쿠폰을 적용할 예약 UUID (id 필드, 예약 번호 아님) |
original_price | number | ✅ | 할인 적용 전 가격 (원, 0 이상). 검증 단계에서 사용한 동일 값 권장 |
응답 (200 OK)
{
"success": true,
"data": {
"reservation_id": "f1e2d3c4-b5a6-7890-fedc-ba9876543210",
"coupon_id": "c1d2e3f4-a5b6-7890-cdef-123456789012",
"coupon_code_id": "d2e3f4a5-b6c7-8901-defa-234567890123",
"discount_amount": 18000,
"parking24_cost": 12600,
"partner_cost": 5400,
"final_price": 162000
},
"error": null
}응답 필드 설명
| 필드 | 타입 | 설명 |
|---|---|---|
reservation_id | string (UUID) | 쿠폰이 적용된 예약 ID |
coupon_id | string (UUID) | 쿠폰 마스터 ID |
coupon_code_id | string (UUID) | null | 1회용 코드 레코드 ID |
discount_amount | number | 적용된 할인액 (원) |
parking24_cost | number | PARKING 24 분담액 (원) |
partner_cost | number | 파트너 분담액 (원, 정산 시 차감) |
final_price | number | 할인 적용 후 최종 가격 (원) |
curl 예시
curl -X POST \
"https://parking24.me/api/partner-api/coupon/apply" \
-H "Authorization: Bearer pk24_live_your_api_key_here" \
-H "Content-Type: application/json" \
-d '{
"code": "SUMMER2026",
"reservation_id": "f1e2d3c4-b5a6-7890-fedc-ba9876543210",
"original_price": 180000
}'웹훅
파트너에 webhook_url이 등록되어 있으면, 예약 상태 변경 시 이벤트가 전송됩니다.
요청 형식
POST {partner.webhook_url}
| 헤더 | 설명 |
|---|---|
Content-Type | application/json |
X-Parking24-Event | 이벤트 타입 (예: reservation.confirmed) |
X-Parking24-Signature | HMAC-SHA256 서명 (요청 본문 기반) |
이벤트 타입
| 이벤트 | 설명 |
|---|---|
reservation.confirmed | 예약 확인 |
reservation.cancelled | 예약 취소 |
Payload schema
최상위 envelope:
| 필드 | 타입 | 설명 |
|---|---|---|
event | string | 이벤트 타입 enum (위 표 참조) |
data | object | 예약 정보 — 아래 schema |
timestamp | string (ISO 8601 UTC) | 이벤트 발생 시각 |
data 필드:
| 필드 | 타입 | 항상 포함 | 설명 |
|---|---|---|---|
reservation_id | string (UUID) | ✅ | 예약 UUID |
reservation_number | string | ✅ | 사용자 노출용 예약 번호 (P24-...) |
airport | string | ✅ | 공항 이름 (한글) |
plan | string | ✅ | 이용권 이름 (DB 설정값 그대로, 예: Standard 또는 한글) |
checkin_date / checkout_date | string (YYYY-MM-DD, KST) | ✅ | 체크인/아웃 일자 |
total_price | integer (KRW) | ✅ | 결제 총액 |
customer_name | string | ✅ | 고객 이름 |
status | string enum | ✅ | CONFIRMED / CANCELLED 등 |
cancellation_fee | integer (KRW) | cancelled 만 | 취소 수수료 (0 가능) |
is_sandbox | boolean | ✅ | sandbox 키로 만든 예약이면 true. 수신측에서 staging/live 분기에 사용. |
요청 본문 예시
reservation.confirmed (live 키 예약):
{
"event": "reservation.confirmed",
"data": {
"reservation_id": "f1e2d3c4-b5a6-7890-fedc-ba9876543210",
"reservation_number": "PK20260310001",
"airport": "인천국제공항",
"plan": "Exclusive",
"checkin_date": "2026-03-10",
"checkout_date": "2026-03-15",
"total_price": 180000,
"customer_name": "홍길동",
"status": "CONFIRMED",
"is_sandbox": false
},
"timestamp": "2026-03-10T01:00:00.000Z"
}reservation.cancelled (sandbox 키 예약):
{
"event": "reservation.cancelled",
"data": {
"reservation_id": "f1e2d3c4-b5a6-7890-fedc-ba9876543210",
"reservation_number": "PK20260310001",
"airport": "인천국제공항",
"plan": "Exclusive",
"checkin_date": "2026-03-10",
"checkout_date": "2026-03-15",
"total_price": 180000,
"cancellation_fee": 5000,
"customer_name": "홍길동",
"status": "CANCELLED",
"is_sandbox": true
},
"timestamp": "2026-03-10T01:00:00.000Z"
}서명 검증
signature = HMAC-SHA256(request_body, key = `${WEBHOOK_SIGNING_SECRET}:${partner_id}`)
WEBHOOK_SIGNING_SECRET은 PARKING 24가 관리하는 서버 시크릿. 파트너에게는 미공개이며, 시크릿이 필요할 경우 PARKING 24 파트너 지원팀에 별도 요청하세요.- Timeout: 5초. 발송 결과는 PARKING 24 내부
webhook_events테이블에 로그되며, 실패 시에도 예약 처리는 정상 진행됩니다.
Rate Limiting
- 윈도우: 60초 슬라이딩 윈도우
- 기본 한도: API 키당 분당 60회 (파트너별 설정 가능)
- 초과 시:
429 Too Many Requests+Retry-After: 60헤더 - 정책: Fail-Open (DB 장애 시 요청 허용)
주차 요금 정책
가격 계산 모델
검색 API(GET /api/partner-api/search) 응답의 original_price / discounted_price는 다음 공식으로 산출됩니다.
totalDays = (checkout_date - checkin_date) 양쪽 포함 일수
total_price = base_price + max(0, totalDays - base_days) × additional_per_day
base_price,base_days,additional_per_day는 공항×이용권 단위로 PARKING 24 어드민에서 관리되는 운영 값입니다.- 제휴사는 별도 계산 없이 검색 API의
original_price(정상가 합계) 또는discounted_price(파트너 할인 적용 후 합계)를 그대로 사용하시는 것을 권장합니다.
인천국제공항(ICN) 현행 운영 기준
⚠️ 아래 값은 2026-05 기준 운영값으로, 실제 적용가는 검색 API 응답을 따릅니다.
Standard (실외) — base_price=50,000 / base_days=5 / additional_per_day=5,000
Pro (실내) — base_price=60,000 / base_days=4 / additional_per_day=10,000
| 일수 | 실외(Standard) | 실내(Pro) |
|---|---|---|
| 1일 | 50,000원 | 60,000원 |
| 2일 | 50,000원 | 60,000원 |
| 3일 | 50,000원 | 60,000원 |
| 4일 | 50,000원 | 60,000원 |
| 5일 | 50,000원 | 70,000원 |
| 6일 | 55,000원 | 80,000원 |
| 7일 | 60,000원 | 90,000원 |
| 8일 | 65,000원 | 100,000원 |
| 9일 | 70,000원 | 110,000원 |
| 10일 | 75,000원 | 120,000원 |
| 11일 | 80,000원 | 130,000원 |
| 12일 | 85,000원 | 140,000원 |
| 13일 | 90,000원 | 150,000원 |
| 14일 | 95,000원 | 160,000원 |
| 15일 | 100,000원 | 170,000원 |
터미널 추가요금
예약 요청 시 terminal 필드(예: T1, T2)를 지정하면 입·출고 시각에 따라 추가요금이 자동 산정됩니다.
추가요금 정책은 검색 API 응답의 surcharges 객체로 노출되며 입출고 각각에 대해 다음 공식이 적용됩니다.
surcharge_per_event = base_surcharge + (isNight ? night_surcharge : 0)
isNight = (hour >= night_start) || (hour < night_end)
인천국제공항 현행 운영 기준
| 터미널 | base_surcharge (입출고 시 기본) | night_surcharge (야간 추가) | 야간 시간대 |
|---|---|---|---|
T1 (제1터미널) | 0원 | 10,000원 | 19:00 ~ 05:00 |
T2 (제2터미널) | 10,000원 | 10,000원 | 19:00 ~ 05:00 |
총 추가요금 = checkin_surcharge + checkout_surcharge (각각 위 공식 적용).
계산 예시 (T2, 입차 22:30, 출차 11:00):
checkin_surcharge= 10,000 + 10,000(야간) = 20,000원checkout_surcharge= 10,000 + 0(주간) = 10,000원- 합계 추가요금 = 30,000원
- 최종
total_price= (검색 응답 가격) + 30,000
terminal 필드를 생략하면 추가요금은 0원으로 적용됩니다.
전기차 제한
이용권별 ev_restricted 플래그가 true인 경우(실내주차장 등) is_electric_vehicle: true로 예약 생성 시 400을 반환합니다. 검색 API 응답에서 각 이용권의 ev_restricted 값을 확인하세요.
가격 모델 변경 안내
위 운영값은 PARKING 24 어드민에서 수시로 조정될 수 있습니다. 제휴사 측에서 가격을 캐싱하지 마시고, 예약 직전 검색 API를 호출하여 최신 가격을 확인하시기 바랍니다.
파트너 할인 체계
파트너별 할인은 검색 API의 discounted_price에 자동 반영됩니다.
| 할인 유형 | 설명 | 예시 |
|---|---|---|
PERCENTAGE | 정상가의 N% 할인 | 10% → 15,000원 → 13,500원 |
FIXED_AMOUNT | 정액 할인 | 2,000원 → 15,000원 → 13,000원 |
파트너별 공항×이용권 조합으로 세부 가격을 별도 설정할 수 있습니다.
AI/LLM 연동
AI 코딩 도구(Cursor, Claude, Windsurf 등)에서 아래 URL을 컨텍스트에 추가하면 API 연동 코드를 자동 생성할 수 있습니다.
https://parking24.me/llms.txt
https://parking24.me/llms-full.txt
주의 사항
- 날짜 형식은 반드시
YYYY-MM-DD를 사용하세요. - 시간 형식은 반드시
HH:MM을 사용하세요. airport_id와plan_id는 UUID 형식이어야 합니다.- 동일 차량 번호로 날짜가 겹치는 예약이 이미 존재할 경우
409에러가 반환됩니다. - API는 파트너 계정에 귀속된 예약만 조회 및 취소할 수 있습니다.
- 파트너별
visible_airport_ids,visible_plan_ids필터가 적용됩니다.
통합 문의 / 연락처
PO 입력 대기 중: 아래 4개 placeholder (
{{...}}) 는partner-api-contact-template.md결정 후 PO가 직접 편집합니다. 채널이 확정되면 이 안내 블록도 삭제하세요.
| 문의 유형 | 채널 |
|---|---|
| 신규 파트너 계정 / Sandbox 키 발급 | 이메일 {{PARTNER_SUPPORT_EMAIL}} |
| Live 키 발급 요청 (sandbox 검증 후) | 이메일 {{PARTNER_SUPPORT_EMAIL}} (수동 승인) |
| 통합 중 기술 문의 (디버깅·schema·webhook) | 이메일 {{PARTNER_SUPPORT_EMAIL}} |
| 보안 사고 / 키 노출 즉시 폐기 | 파트너 포털 /partner/api-keys 에서 즉시 폐기 + 전화 {{PARTNER_SUPPORT_PHONE}} |
| Webhook 서명 시크릿 요청 | 이메일 {{PARTNER_SUPPORT_EMAIL}} |
응답 시간: {{PARTNER_SUPPORT_HOURS}} / SLA: {{PARTNER_SUPPORT_SLA}}
계정/키 발급 요청 시 포함: 회사명, 사업자번호, 통합 담당자 이름·이메일, 예상 월 트래픽(예약 건수), 서비스 형태(B2B/B2C).
변경 이력은
partner-api-changelog.md또는 파트너 포털/partner/dashboard공지 카드에서 확인하세요. 채널 변경 시 본 문서가 우선 갱신됩니다.