입점 신청하기내 파트너센터 바로가기
개발가이드

공통 규약

인증·응답 형식·오류 처리·호출 한도·재시도 — 모든 API에 똑같이 적용되는 규칙이에요.

인증

모든 요청에 X-Api-Key 헤더로 API Key를 담아 보내요.

X-Api-Key: vpk_live_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

키에는 기능별 권한(스코프)이 붙어요. 권한이 없는 API를 호출하면 403 SCOPE_FORBIDDEN이에요.

스코프범위
orders:read주문 조회
orders:write주문 처리
claims:read클레임 조회
claims:write클레임 처리
qna:read문의 조회
qna:write문의 답변

응답 형식

모든 응답은 metadata로 감싼 형식이에요.

{
  "meta": { "code": 200, "message": "OK", "error_code": null, "error_data": null },
  "data": { "order_no": "VR20260826-0000001" }
}

실패 응답도 형식이 같고 datanull이에요.

{
  "meta": {
    "code": 422,
    "message": "status_changed_to와 status_changed_at_gte/lte는 함께 지정해야 합니다.",
    "error_code": "STATUS_CHANGED_FILTER_INCOMPLETE",
    "error_data": null
  },
  "data": null
}
분기는 error_code로
오류 분기는 반드시 meta.error_code로 처리해 주세요. meta.message는 사람이 읽는 안내라서 예고 없이 다듬어져요. 전체 오류 코드 목록은 API 레퍼런스 상단에 있어요.

시각 표기

  • 요청 파라미터는 ISO 8601로 보내요. 예: 2026-08-26T00:00:00+09:00
  • 오프셋을 생략하면 UTC로 해석해요. 한국 시각으로 조회하려면 +09:00을 붙여 주세요.
  • 응답의 모든 시각은 UTC이고 Z로 끝나요. 예: 2026-08-26T01:12:33.482910Z
URL에 넣을 때 + 인코딩 주의
쿼리스트링의 +는 공백으로 해석돼요. +09:00을 URL에 직접 이어 붙이면 서버에는 00:00:00 09:00으로 도착해 422 오류가 나요. URL을 직접 조립한다면 +%2B로 인코딩하거나(2026-08-26T00:00:00%2B09:00), UTC 기준 Z 표기(2026-08-25T15:00:00Z)를 사용해 주세요. 대부분의 HTTP 클라이언트 라이브러리는 파라미터를 자동 인코딩하므로 그대로 쓰면 돼요.

목록 조회와 페이지 넘김

목록 응답은 { "list": [...], "next_cursor": "..." } 형태예요.

  1. 첫 페이지cursor 없이 요청해요.
  2. 다음 페이지응답의 next_cursor그대로 다음 요청의 cursor에 넣어요.
  3. 마지막 판정next_cursornull이면 마지막 페이지예요.
  • cursor는 서버가 발급한 값이에요. 직접 만들거나 고쳐 보내면 422 INVALID_CURSOR이고, 그때는 cursor 없이 처음부터 다시 수집하면 복구돼요.
  • 총 건수(total)는 제공하지 않아요. 마지막 페이지 판정은 next_cursor === null로만 해 주세요.
  • limit은 1~100이고 생략하면 50이에요.

호출 한도

대상한도
조회 API 호출분당 60회
처리 API 호출분당 30회
조회로 반환되는 행 수분당 3,000행
  • 행 수는 조회 API 전체가 함께 쓰는 하나의 한도예요. 커서로 다음 페이지를 받을 때도 그 페이지의 행 수가 누적돼요.
  • 초과하면 429 RATE_LIMITEDRetry-After(초) 헤더가 와요. 그 시간만큼 기다린 뒤 재시도해 주세요.
  • 응답 헤더 X-RateLimit-Limit·X-RateLimit-Remaining으로 남은 호출 수를 확인할 수 있어요.
  • 503 RATE_LIMIT_UNAVAILABLE은 서버가 한도를 확인할 수 없어 요청을 처리하지 않은 상태예요. 요청이 반영되지 않았으니 잠시 후 재시도하면 돼요.
재시도 기준
429·503은 Retry-After를 지켜 지수 백오프로 재시도해요. 400·401·403·404·422는 요청 자체를 고치기 전까지 결과가 같으니 그대로 재시도하지 마세요.
409는 하나로 묶어 다루면 안 돼요 — 같은 키로 재시도해야 풀리는 것도 있고, 새 키가 필요한 것도 있어요. 아래 error_code별 대응표를 따라 주세요.

멱등 — 처리 API 재시도 규칙

모든 처리(POST) API는 Idempotency-Key 헤더가 필수예요. 없으면 422 IDEMPOTENCY_KEY_REQUIRED예요.

Idempotency-Key: 6b1f7a52-3c9e-4d18-9a77-0f2c5e8b4d31
  • 요청마다 새로 만든 고유 문자열을 써요(UUID 권장, 200자 이하).
  • 타임아웃·네트워크 오류로 재시도할 때는 처음과 같은 키를 보내요. 서버가 저장해 둔 첫 결과를 그대로 돌려주므로 이중 처리가 일어나지 않아요.
  • 재시도가 아닌 새 작업에는 반드시 새 키를 써요.

응답별 대응

이 표가 정본이에요. 409를 한 덩어리로 묶어 "재시도 금지"로 처리하면 IN_PROGRESS처럼 재시도로만 풀리는 상황에서 처리가 영영 완료되지 않아요.

응답의미대응
200처리 완료(또는 이미 그 상태)결과 반영
409 IDEMPOTENCY_IN_PROGRESS같은 키의 요청이 아직 처리 중수 초 후 같은 키로 재시도. 새 키로 바꿔 보내면 이중 처리가 돼요
409 IDEMPOTENCY_KEY_REUSED같은 키로 내용이 다른 요청을 보냄새 키로 다시 보내고, 키 생성 로직을 점검해요
409 IDEMPOTENCY_UNRESOLVED현재 상태에서 그 처리를 확정할 수 없음상세 조회 후 판단. 원하는 처리가 이미 반영됐으면 완료로 보고, 아니면 available_actions에 맞춰 다시 설계해요
409 SHIPMENT_STATE_CONFLICT이미 다른 송장이 등록돼 있음주문 조회로 등록된 송장을 확인. 정정은 파트너센터에서만 돼요
410 IDEMPOTENCY_RESULT_EXPIRED처리는 이미 성공했고, 24시간이 지나 응답 본문만 삭제됨아래 절차 — 상태를 확인하기 전에는 새 키로 보내지 않아요

410을 받았을 때

처리는 이미 됐지만 그 결과 본문이 더 이상 없다는 뜻이에요. 같은 키로 다시 보내는 것 자체는 안전해요 — 계속 410이 올 뿐 처리가 두 번 일어나지는 않아요. 위험한 건 상태를 확인하지 않고 새 키로 재전송하는 쪽이에요. 그때는 서버가 새 작업으로 받아들여 같은 처리가 한 번 더 일어나요.

  1. 현재 상태 조회주문이면 GET /open/v1/orders/{order_no}의 라인 상태·송장을, 클레임이면 GET /open/v1/claims/{claim_no}를 확인해요.
  2. 이미 반영됐으면원하는 상태가 이미 반영돼 있으면 완료로 처리해요. 새 키로 보내지 마세요.
  3. 반영되지 않았으면그때 Idempotency-Key로 다시 보내요.

결과가 같으면 성공이에요

처리 API는 "이 주문을 이 상태로 만들어 달라"는 요청으로 동작해요. 이미 그 상태면 아무것도 바꾸지 않고 200으로 응답해요. 응답 항목의 already_donetrue면 이번 호출 전에 이미 그 상태였다는 뜻이에요.

송장은 carrier_name·tracking_no·logistics_company 세 값이 모두 같아야 같은 송장으로 봐요. 셋 다 같으면 아무것도 바꾸지 않고 200이고, 하나라도 다르면 409 SHIPMENT_STATE_CONFLICT예요. logistics_company는 선택 항목이지만 재전송 때 빠뜨리면 「값 있음 ↔ null」 차이로 409가 나니 처음 보낸 값을 그대로 다시 보내 주세요. 409를 받으면 주문 조회로 등록된 송장을 확인해 주세요.