운임 견적 API
POST /v1/fulfillment/shipping/quotes는 목적지, 무게, 치수, 상품 속성, 서비스로 국제 운임을 견적합니다.
창고 분할이 아직 모르면 단일 포장 단축 필드를 사용하세요. 포장 수와 포장별 측정값이 이미 있으면 **packages[]**를 사용하세요.
이 엔드포인트는 배송 채널 API와 같은 채널, 권역, 서비스, 과금, 금액 용어를 사용합니다.
https://api.hiobuy.com/v1/fulfillment/shipping/quotes견적은 예산이지 확정 가격이 아닙니다. 창고 계량, 부피 측정, 재포장, 서비스 검토에 따라 최종 금액이 바뀔 수 있습니다.
COMPLETE견적도 가격 확정이 아닙니다.
호환 별칭: POST /v1/fulfillment/shipments/freight/estimate(동일 동작). /v1/fulfillment/shipping/quotes를 우선하세요.
금액과 단위 {#units}
- 금액
amount값은 모두 정수 CNY fen입니다.5000은 ¥50.00을 의미합니다. - 최상위
monetary_unit은 항상CNY_minor입니다. - 금액 객체는
{ "amount": 5000, "currency": "CNY" }입니다. - 요청 무게는 항상
KG. 포장 치수는 항상CM. - 채널과 서비스는
name이 아니라 안정적인 code로 식별하세요.
요청 헤더 {#request}
POST /v1/fulfillment/shipping/quotes
Authorization: Bearer hio_live_xxx
Content-Type: application/json
Language: en표시 언어는 Language 헤더만 사용합니다. 지원 값: en(기본값), en-US, zh, zh-CN, zh-TW, cn, hk. JSON 본문이나 쿼리 문자열에 language를 넣지 마세요.
두 가지 요청 형식 {#request-formats}
단일 포장 단축 필드(
weight_kg,length_cm,width_cm,height_cm)와packages[]를 함께 쓰지 마세요. 혼합 요청은400 VALIDATION_ERROR로 거부됩니다.
형식 A — 단일 포장 단축 {#format-a}
목적지와 추정 총 무게는 알지만, 창고가 상자를 어떻게 나눌지는 모를 때 사용합니다.
최소 요청:
{
"destination": {
"country_code": "KR"
},
"weight_kg": 2.05
}치수가 있는 단일 포장:
{
"destination": {
"country_code": "KR",
"postal_code": "04524"
},
"weight_kg": 2.05,
"length_cm": 30,
"width_cm": 20,
"height_cm": 10,
"attributes": []
}weight_kg는 추정 출고 무게(KG)입니다.length_cm,width_cm,height_cm는CM입니다. 세 값을 모두 보내거나 세 값을 모두 생략하세요.- 최종 창고 분할이 불명확하면 이 형식을 우선하세요. 치수가 없으면 부피 과금 채널에서
PARTIAL또는REVIEW_REQUIRED가 나올 수 있습니다.
형식 B — 알려진 포장 {#format-b}
상자 수와 각 상자 데이터가 이미 있으면 packages[]를 사용합니다.
신고된 단일 포장:
{
"destination": {
"country_code": "KR"
},
"packages": [
{
"reference": "box-1",
"weight": {
"value": 2.05,
"unit": "KG"
},
"dimensions": {
"length": 30,
"width": 20,
"height": 10,
"unit": "CM"
}
}
]
}복수 포장:
{
"destination": {
"country_code": "KR",
"postal_code": "04524"
},
"packages": [
{
"reference": "box-1",
"weight": {
"value": 1.25,
"unit": "KG"
},
"dimensions": {
"length": 30,
"width": 20,
"height": 10,
"unit": "CM"
}
},
{
"reference": "box-2",
"weight": {
"value": 0.8,
"unit": "KG"
},
"dimensions": {
"length": 20,
"width": 15,
"height": 8,
"unit": "CM"
}
}
]
}packages[] 규칙(OpenAPI):
- 1–200개 포장.
- 요소 1개는 명시적 단일 포장입니다. 여러 요소는 명시적 복수 포장 출고입니다.
reference는 선택 사항이지만 요청 안에서 고유해야 합니다.packages[].weight는 필수입니다.packages[].weight.unit은KG여야 합니다.packages[].dimensions는 선택 사항입니다. 있으면length,width,height,unit이 모두 필요합니다.unit은CM이어야 합니다.
Gateway는 형식 A를 창고 단일 포장으로 매핑합니다. 형식 B는 신고값 그대로 검증·매핑됩니다. 최종 분할과 실측 치수는 창고 처리 후에 결정됩니다.
공통 요청 필드 {#shared-fields}
두 형식 모두 다음을 포함할 수 있습니다.
destination
| 필드 | 필수 | 설명 |
|---|---|---|
country_code | 예 | ISO 3166-1 alpha-2, 두 글자 |
subdivision_code | 아니요 | 예: US-CA. 국가 접두사는 country_code와 일치해야 합니다. |
region | 아니요 | 행정구역 표시 이름. 유효한 subdivision_code가 우선합니다. |
postal_code | 아니요 | 문자열. 앞자리 0을 유지하세요. |
declared_value
{
"amount": 5000,
"currency": "CNY"
}출고 수준 신고 가액. 정수 CNY fen. 모르면 필드를 생략하세요. 모름을 의미하려고 0을 보내지 마세요.
attributes
GET /v1/fulfillment/shipments/item-attributes의 안정적인 상품 속성 코드 배열. 고유 문자열, 최대 100개.
견적은 먼저 destination.country_code에 적용되는 채널로 제한되며 다른 국가용 채널은 제외됩니다. 남은 각 채널은 신고된 속성을 개별적으로 판정합니다. 미지원 속성이 있으면 해당 채널은 ATTRIBUTE_NOT_SUPPORTED와 함께 UNAVAILABLE이 되지만, 다른 적용 가능한 채널은 계속 견적을 반환할 수 있습니다.
services
{
"services": {
"channel": [
{
"code": "LINE_INSURANCE",
"quantity": 1
}
],
"outbound": [
{
"code": "VACUUM_PACKING",
"quantity": 1
}
],
"inbound": [
{
"code": "PHOTO",
"quantity": 3
}
]
}
}| 그룹 | 의미 |
|---|---|
channel | 채널 부가 서비스. 코드는 채널의 value_added_services[].code입니다. |
outbound | 출고 창고 처리 |
inbound | 입고 창고 처리 |
각 항목에 code와 quantity가 필요합니다. OpenAPI: quantity는 1에서 999까지의 정수입니다. 코드는 각 그룹 안에서 고유해야 합니다.
channel_codes
견적 집합을 제한하는 안정적인 채널 코드. 생략하면 후보 채널 전체를 견적합니다. 빈 배열은 보내지 마세요. 알 수 없거나 접근할 수 없는 코드는 요청 전체에 400 INVALID_SHIPPING_CHANNEL을 반환합니다.
완전한 요청 예 {#complete-request}
형식 A. 목적지, 치수, 신고 가액, 속성, 서비스, 채널 필터 포함:
{
"destination": {
"country_code": "US",
"subdivision_code": "US-CA",
"region": "California",
"postal_code": "90001"
},
"weight_kg": 2.05,
"length_cm": 30,
"width_cm": 20,
"height_cm": 10,
"declared_value": {
"amount": 5000,
"currency": "CNY"
},
"attributes": [
"GENERAL_CARGO"
],
"services": {
"channel": [
{
"code": "LINE_INSURANCE",
"quantity": 1
}
],
"outbound": [
{
"code": "VACUUM_PACKING",
"quantity": 1
}
],
"inbound": [
{
"code": "PHOTO",
"quantity": 3
}
]
},
"channel_codes": [
"US-SEA"
]
}응답 {#response}
{
"success": true,
"estimate_type": "DECLARED",
"completeness": {
"level": "HIGH",
"destination": "COMPLETE",
"package_dimensions": "COMPLETE",
"package_split": "DECLARED",
"declared_value": "PROVIDED",
"attributes": "DECLARED",
"services": "REQUESTED_ONLY"
},
"warnings": [
{
"code": "WAREHOUSE_REVIEW_REQUIRED",
"message": "Final charges require warehouse measurement, packing and service review.",
"affects": [
"FINAL_CHARGES"
]
}
],
"quotes": [
{
"channel": {
"code": "US-SEA",
"name": "US Ocean",
"description": "General cargo line",
"tags": [
"GREAT_VALUE"
],
"capabilities": {
"delivery_methods": [
"DOOR_DELIVERY",
"PICKUP"
]
}
},
"available": true,
"quote_status": "COMPLETE",
"unavailable_reason": null,
"attribute_evaluation": {
"status": "SUPPORTED",
"declared_attributes": [
{
"code": "GENERAL",
"name": "General cargo"
}
],
"accepted_attributes": [
{
"code": "GENERAL",
"name": "General cargo"
}
],
"unsupported_attributes": []
},
"matched_region": {
"code": "US-WEST",
"name": "US West",
"match_type": "COUNTRY_REGION"
},
"packages": [
{
"reference": "box-1",
"weight": {
"value": 2.05,
"unit": "KG"
},
"dimensions": {
"length": 30,
"width": 20,
"height": 10,
"unit": "CM"
},
"weights": {
"actual": {
"value": 2.05,
"unit": "KG"
},
"volumetric": {
"value": 1,
"unit": "KG"
},
"chargeable": {
"value": 2.5,
"unit": "KG"
}
}
}
],
"weights": {
"actual": {
"value": 2.05,
"unit": "KG"
},
"volumetric": {
"value": 1,
"unit": "KG"
},
"chargeable": {
"value": 2.5,
"unit": "KG"
}
},
"billing_quantity": {
"value": 2.5,
"unit": "KG"
},
"pricing_selector": {
"type": "WEIGHT",
"value": 2.5,
"unit": "KG",
"scope": "SHIPMENT"
},
"transit_time": {
"text": "15-18 business days",
"min_business_days": 15,
"max_business_days": 18
},
"charges": {
"base_freight": {
"amount": 10000,
"currency": "CNY"
},
"channel_services": {
"amount": 550,
"currency": "CNY",
"known_amount": 550,
"calculation_status": "CALCULATED",
"items": []
},
"channel_rules": {
"amount": 0,
"currency": "CNY",
"known_amount": 0,
"calculation_status": "CALCULATED",
"items": [],
"aggregation": "SUM_ALL",
"cap": null
},
"outbound_services": {
"amount": 800,
"currency": "CNY",
"known_amount": 800,
"calculation_status": "CALCULATED",
"items": []
},
"inbound_services": {
"amount": 300,
"currency": "CNY",
"known_amount": 300,
"calculation_status": "CALCULATED",
"items": []
},
"adjustments": {
"amount": 0,
"currency": "CNY",
"known_amount": 0,
"calculation_status": "CALCULATED",
"items": []
}
},
"display_charges": {
"addition": {
"amount": 0,
"currency": "CNY",
"included_in_total": false
},
"floor": {
"amount": 0,
"currency": "CNY",
"included_in_total": false
}
},
"total": {
"amount": 11650,
"currency": "CNY"
},
"known_total": {
"amount": 11650,
"currency": "CNY"
},
"warnings": [],
"service_adjustment_possible": true
}
],
"monetary_unit": "CNY_minor",
"generated_at": "2026-09-07T08:00:00Z",
"request_id": "req_xxx",
"disclaimer": "Estimated charges based on declared data."
}최상위 필드
| 필드 | 설명 |
|---|---|
success | 일부 견적이 UNAVAILABLE이어도 견적 성공 시 true. |
estimate_type | DECLARED — 신고 데이터 기반이며 창고 실측이 아닙니다. |
completeness | 입력이 얼마나 완비되었는지. 배송 가능 보장이 아닙니다. |
warnings | 출고 수준 경고. |
quotes | 채널별 결과: 완전, 부분/검토, 이용 불가 순. |
monetary_unit | 항상 CNY_minor. |
generated_at | 응답 시각. |
request_id | x-request-id와 대조합니다. |
disclaimer | 사람이 읽을 수 있는 견적 면책. |
completeness
| 필드 | 의미 |
|---|---|
level | 전체 입력 커버리지. 예: HIGH. |
destination | 목적지 완비도(국가가 있으면 COMPLETE). |
package_dimensions | 세로/가로/높이가 제공되었는지. |
package_split | packages[]를 보냈으면 DECLARED. 단축 형식은 단일 포장으로 간주합니다. |
declared_value | PROVIDED, 또는 생략/모름. |
attributes | 상품 속성이 신고되었는지. |
services | 선택한 서비스를 보냈으면 REQUESTED_ONLY. 창고가 더 추가할 수 있습니다. |
견적 상태 {#quote-status}
available만으로 판단하지 마세요. 항상 quote_status를 읽으세요.
quote_status | available | total | 의미 |
|---|---|---|---|
COMPLETE | true | 금액 객체 | 표시해도 되는 완전한 예산. 그래도 확정이 아닙니다. |
PARTIAL | true | 보통 null | 입력 부족. 경고를 읽고 치수, 우편번호, 신고 가액을 추가하세요. |
REVIEW_REQUIRED | true | 보통 null | 창고 실측 또는 인력 검토가 필요합니다. |
UNAVAILABLE | false | null | 이 채널은 견적할 수 없습니다. HTTP 요청 자체는 성공했습니다. |
total은 알 수 있을 때의 완전한 예산입니다.known_total은 지금 계산할 수 있는 요금의 합입니다.total이null이면known_total을 완전한 견적으로 취급하지 마세요.unavailable_reason.code는 프로그램 처리용입니다.unavailable_reason.message는 표시 전용입니다.
한 견적의 UNAVAILABLE은 HTTP 오류가 아닙니다.
견적 객체 {#quotes}
| 필드 | 설명 |
|---|---|
channel | { code, name, description, tags, capabilities } — 채널 카탈로그와 같은 식별자. |
channel.capabilities.delivery_methods | 하위 호환되는 선택적 배열입니다. 안정 코드: DOOR_DELIVERY, PICKUP, POST_OFFICE_PICKUP. 모든 견적 상태에서 반환될 수 있으며 기존 클라이언트는 무시할 수 있습니다. |
available | 이 채널이 사용 가능한 견적을 냈는지. quote_status와 함께 보세요. |
quote_status | COMPLETE · PARTIAL · REVIEW_REQUIRED · UNAVAILABLE. |
unavailable_reason | { code, message } 또는 null. |
attribute_evaluation | 채널별 선택적 판정 결과: SUPPORTED, UNSUPPORTED, NOT_DECLARED 및 신고·허용·미지원 속성 목록. |
matched_region | { code, name, match_type } 또는 null. |
packages | 신고 또는 매핑된 포장과 포장별 무게. |
weights | 출고 수준 actual / volumetric / chargeable(KG). |
billing_quantity | 채널이 실제로 과금하는 수량. 단위는 KG, M3, 또는 KG_PER_M3. |
pricing_selector | 그 수량이 요율표 구간에 어떻게 맞았는지(type, value, unit, scope). |
transit_time | 참고 운송 소요 시간. |
charges | 요금 그룹. 아래를 참고하세요. |
display_charges | 선택적 UI 전용 행. included_in_total이 false이면 total에 더하지 마세요. |
total / known_total | 완전한 예산 vs 현재 알려진 요금. |
warnings | 채널 수준 경고. |
service_adjustment_possible | 창고 처리로 서비스와 요금이 아직 바뀔 수 있으면 true. |
무게와 과금 수량 {#weights}
actual— 신고 또는 실측 무게.volumetric— 부피 중량.chargeable— 운임에 쓰는 무게.billing_quantity— 채널이 과금하는 수량(무게, 부피, 밀도일 수 있음).pricing_selector— 그 수량이 요금 행을 어떻게 선택했는지. 유형은 카탈로그WEIGHT/VOLUME/DENSITY와 같습니다.- 복수 포장 채널은 상자마다 반올림한 뒤 합산할 수 있습니다.
pricing_selector.scope가PER_PACKAGE이면 각packages[].pricing_selector를 읽으세요.
요금 {#charges}
| 그룹 | 의미 |
|---|---|
base_freight | 기본 국제 운임 |
channel_services | 필수 및 개발자 선택 채널 서비스 |
channel_rules | 과대, 과중, 신고 가액 및 기타 노선 규칙 |
outbound_services | 배송 준비 / 출고 처리 단계의 부가 서비스 |
inbound_services | 창고 수령 / 입고 처리 단계의 부가 서비스 |
adjustments | 조정 |
입고 및 출고 서비스
inbound_services와 outbound_services는 창고 부가 서비스의 서로 다른 단계입니다. 입고 서비스는 창고 수령 시 수행되며 패키지 사진, 동영상 촬영, 검수 등이 포함됩니다. 출고 서비스는 배송 준비 시 수행되며 패키지 보강, 진공 포장, 목재 프레임/상자 포장 등이 포함됩니다. 동일한 패키지나 배송에 두 단계의 서로 다른 서비스가 모두 적용되고 정당하게 청구될 수 있습니다.
Shipping Quote의 금액은 적용 가능한 서비스의 예상값일 뿐이며, 견적 조회 자체가 추가 서비스 요금을 발생시키지는 않습니다. 실제 요금은 수행된 서비스와 최종 가격 및 정산에 따라 결정됩니다. 총 풀필먼트 비용을 예상할 때 두 그룹을 모두 사용하고 각 예상액을 해당 최종 실제 요금과 대조하십시오. 동일한 개별 서비스의 예상액을 최종 요금에 다시 더하지 마십시오.
CNY 최소 단위 예시: 패키지 사진 50 fen(¥0.50), 검수 100 fen(¥1.00), 진공 포장 150 fen(¥1.50), 패키지 보강 200 fen(¥2.00). 서로 다른 풀필먼트 단계에서 수행되는 별도 서비스이므로 네 항목이 모두 함께 존재할 수 있습니다.
각 그룹에는 보통 다음이 포함됩니다:
| 필드 | 의미 |
|---|---|
amount | 그룹 합계(fen). 모르면 null |
currency | CNY |
known_amount | 지금 계산할 수 있는 항목 합 |
calculation_status | 예: CALCULATED |
items | 세부 항목 |
channel_rules에는 aggregation과 cap도 있을 수 있습니다. 그룹 소계를 사용하세요. 원시 규칙 항목을 합산해 대체하지 마세요.
SUM_ALL은 일치한 모든 요금을 합산합니다. HIGHEST_ONLY는 금액 내림차순에서 최고 요금 하나만 선택하며 동일 금액 규칙은 동등합니다. cap=null은 상한 없음입니다. 규칙 항목의 reason은 표시 전용입니다. 프로그램 로직에는 condition_match, matched_conditions, rule_type, charge_mode, charge_value, outcome, missing_fields를 사용하세요. PENDING_INPUT, REVIEW_REQUIRED 및 기타 미계산 규칙은 알려진 합계에서 제외됩니다. amount=null은 0이 아니며 구성된 charge_value는 실제 청구액이 아닙니다.
요금 항목
| 필드 | 의미 |
|---|---|
code | 안정적인 요금 또는 서비스 코드 |
name | 현지화된 표시 이름 |
category | 요금 범주 |
source | MANDATORY · DEVELOPER_SELECTED · RULE_ENGINE |
pricing_basis | 행이 과금된 방식 |
quantity | 행의 과금 수량 |
unit_price | 알 수 있을 때의 단가(fen) |
amount | 행 합계. null은 모름이며 0이 아닙니다. |
estimated | 행이 아직 추정인지 |
calculation_status | 계산 상태 |
affected_by_packages | 포장 수/크기가 이 행을 바꿀 수 있는지 |
included_in_total | false이면 total에 다시 더하지 마세요 |
display_charges는 프론트엔드 표시 전용으로만 존재할 수 있습니다.
이용 불가 사유 {#unavailable-reasons}
자주 쓰는 unavailable_reason.code 값:
OUTSIDE_PRICING_RANGE
POSTAL_CODE_REQUIRED
POSTAL_CODE_NOT_SUPPORTED
DESTINATION_NOT_SUPPORTED
ATTRIBUTE_NOT_SUPPORTED
SERVICE_NOT_SUPPORTED
DIMENSIONS_REQUIRED
DECLARED_VALUE_REQUIRED
MULTI_PACKAGE_NOT_SUPPORTED
PRICING_MODE_UNSUPPORTED
CHANNEL_RULE_REJECTED
CHANNEL_PRICING_ERROR이용 불가 채널은 quotes[]에 남아 거절 이유를 설명할 수 있습니다.
카탈로그 용어 {#catalog-terminology}
| 배송 채널 | 이 API | 의미 |
|---|---|---|
items[].code/name/description/tags | quotes[].channel.* | 같은 채널 |
regions[].code/name/match_type | quotes[].matched_region.* | 견적이 선택한 권역 |
value_added_services[].code | services.channel[].code 및 요금 code | 안정적인 서비스 코드 |
billing.quantity_unit | billing_quantity.unit / pricing_selector.unit | 과금 단위 |
rule_summary.aggregation | charges.channel_rules.aggregation | 규칙 집계 |
rule_summary.cap | charges.channel_rules.cap | 집계 후 상한; null은 상한 없음 |
상품 속성 {#item-attributes}
GET /v1/fulfillment/shipments/item-attributes는 견적에 유효한 attributes[] 코드를 반환합니다.
오류 {#errors}
| HTTP | error.code | 발생 시점 |
|---|---|---|
| 400 | VALIDATION_ERROR | 구조 오류, 요청 형식 혼합, KG/CM 단위, 중복 코드, 또는 빈 channel_codes |
| 400 | INVALID_SHIPPING_CHANNEL | 요청한 channel_codes 값이 알려지지 않았거나 앱에 보이지 않음 |
| 401 | INVALID_API_KEY | Bearer 토큰이 없거나 유효하지 않음 |
| 403 | FULFILLMENT_MODE_NOT_SUPPORTED | 앱이 자체 풀필먼트 |
| 403 | WAREHOUSE_AUTH_INVALID | 창고 인가가 없거나 거부되었거나 만료됨 |
| 422 | INVALID_COUNTRY_CODE | 목적지 국가가 유효하지 않음 |
| 422 | INVALID_ITEM_ATTRIBUTE | 속성 코드가 유효하지 않음 |
| 502 | WAREHOUSE_UPSTREAM_ERROR | 창고 서비스 실패. 백오프로 재시도 |
공개용 독립 코드 AUTHENTICATION_ERROR, WAREHOUSE_AUTH_REQUIRED, WAREHOUSE_SERVICE_UNAVAILABLE은 없습니다. 401 INVALID_API_KEY, 403 WAREHOUSE_AUTH_INVALID, 502 WAREHOUSE_UPSTREAM_ERROR를 사용합니다.
이 출고를 운송할 수 없는 채널은 HTTP 실패가 아니라 UNAVAILABLE 견적입니다.
관련 {#related}
Get Support
Need integration help? Contact Developer Support at support@hiobuy.com · Response within 1–2 business days