Channel API v2 가이드

HATEOAS 토큰 기반의 v2 API를 사용하여 숙소 검색부터 예약까지 완전한 흐름을 구현합니다.

Channel API v2 가이드

v2 API는 HATEOAS(Hypermedia as the Engine of Application State) 패턴을 채택한 새로운 Channel API입니다. 각 단계에서 발급된 토큰이 다음 단계로 연결되므로, 파라미터를 직접 조합하지 않고 응답에 포함된 링크를 따라가는 방식으로 예약 흐름을 구성합니다.

v1과의 주요 차이점

항목v1v2
인증 방식X-Api-Key 헤더X-Api-Key 헤더 (동일)
예약 흐름독립적인 API 호출 조합토큰으로 연결된 4단계 흐름
가격 검증별도 검증 없음Price Check 단계에서 가격 재확인 후 book 토큰 발급
ID 형식숫자형 property_idproperty_id는 문자열, room/rate는 해시 ID
인원 형식adults, children 별도 파라미터EPS 호환 occupancy 파라미터 ("2", "2-3,5")
숙소 목록없음페이지 토큰 기반 페이지네이션
콘텐츠 API없음숙소 상세, 객실 타입 조회 추가

v2 API의 기본 경로는 /api/channel/v2/ 입니다. v1과 동일한 API 키를 사용하며, 기존 v1 엔드포인트는 계속 지원됩니다.

전체 엔드포인트 목록

HTTP 메서드경로설명
GET/api/channel/v2/properties숙소 목록 조회 (페이지네이션)
GET/api/channel/v2/properties/{id}숙소 상세 조회
GET/api/channel/v2/properties/{id}/roomtypes객실 타입 목록 조회
GET/api/channel/v2/properties/availability가용성 검색 (Step 1)
GET/api/channel/v2/properties/{propertyId}/rooms/{roomId}/rates/{rateId}가격 확인 (Step 2)
POST/api/channel/v2/bookings예약 생성 (Step 3)
GET/api/channel/v2/bookings/retrieve예약 조회 (Step 4a)
PUT/api/channel/v2/bookings/cancel예약 취소 (Step 4b)

예약 4단계 흐름

v2의 예약 흐름은 토큰으로 연결된 4단계로 구성됩니다.

Step 1: Availability Search

날짜/인원으로 가용 객실을 검색합니다. 응답의 각 요금에 price_check 링크(토큰 포함)가 포함됩니다.

Step 2: Price Check

price_check 링크를 호출하여 가격을 재확인합니다. 성공 시 book 토큰이 발급됩니다.

Step 3: Booking

book 토큰과 투숙객 정보로 예약을 생성합니다. 응답에 retrievecancel 링크가 포함됩니다.

Step 4: Retrieve / Cancel

retrieve 링크로 예약 상세를 조회하거나, cancel 링크로 예약을 취소합니다.


Step 1: 가용성 검색

GET /api/channel/v2/properties/availability

날짜, 인원, 숙소 ID를 지정하여 가용 객실과 요금을 조회합니다.

쿼리 파라미터

파라미터필수설명예시
checkin체크인 날짜2026-04-01
checkout체크아웃 날짜2026-04-03
occupancy인원 (반복 가능)2 또는 2-3,5
property_id숙소 ID (반복 가능)12345
currency-통화 코드 (기본값: KRW)KRW
language-언어 코드 (기본값: ko-KR)ko-KR

occupancy 형식: EPS 호환 포맷을 사용합니다.

  • "2" — 성인 2명
  • "2-3,5" — 성인 2명, 어린이 3세·5세

Step 1: 가용성 검색

응답 구조

[
  {
    "property_id": "12345",
    "status": "available",
    "rooms": [
      {
        "id": "a1b2c3d4",
        "room_name": "디럭스 더블룸",
        "rates": [
          {
            "id": "e5f6g7h8",
            "status": "available",
            "available_rooms": 5,
            "refundable": true,
            "occupancy_pricing": {
              "2": {
                "nightly": [
                  [
                    { "type": "base_rate", "currency": "KRW", "value": 150000 },
                    { "type": "tax_and_service_fee", "currency": "KRW", "value": 15000 }
                  ],
                  [
                    { "type": "base_rate", "currency": "KRW", "value": 150000 },
                    { "type": "tax_and_service_fee", "currency": "KRW", "value": 15000 }
                  ]
                ],
                "totals": {
                  "inclusive": {
                    "request_currency": { "currency": "KRW", "value": 330000 }
                  }
                }
              }
            },
            "bed_groups": {
              "37321": {
                "id": "37321",
                "description": "1 King Bed",
                "links": {
                  "price_check": {
                    "method": "GET",
                    "href": "/api/channel/v2/properties/12345/rooms/a1b2c3d4/rates/e5f6g7h8?token=eyJ...",
                    "expires": "2026-04-01T10:30:00.000Z"
                  }
                }
              }
            },
            "cancel_penalties": [],
            "amenities": {},
            "promotions": null,
            "deposits": []
          }
        ]
      }
    ]
  }
]

price_check 토큰에는 유효 기간이 있습니다. expires 필드를 확인하고, 만료 전에 Step 2를 호출하세요. 만료된 토큰으로 요청하면 410 Gone이 반환됩니다.


Step 2: 가격 확인 (Price Check)

GET /api/channel/v2/properties/{propertyId}/rooms/{roomId}/rates/{rateId}?token=

Step 1 응답의 price_check 링크를 그대로 호출합니다. URL을 직접 조합하지 말고 응답에 포함된 href를 사용하세요.

경로 파라미터

파라미터설명
propertyId숙소 ID (Step 1 property_id)
roomId객실 해시 ID (Step 1 rooms[].id)
rateId요금 해시 ID (Step 1 rooms[].rates[].id)

쿼리 파라미터

파라미터필수설명
tokenStep 1에서 발급된 price_check 토큰

Step 2: 가격 확인

응답 구조

{
  "status": "matched",
  "occupancy_pricing": {
    "2": {
      "nightly": [...],
      "totals": {
        "inclusive": {
          "request_currency": { "currency": "KRW", "value": 330000 }
        }
      }
    }
  },
  "links": {
    "book": {
      "method": "POST",
      "href": "/api/channel/v2/bookings?token=eyJ...",
      "expires": "2026-04-01T11:00:00.000Z"
    }
  }
}

status 필드:

  • "matched" — 가격이 Step 1과 동일합니다.
  • "price_changed" — 가격이 변경되었습니다. occupancy_pricing에 최신 가격이 반영됩니다. 변경된 가격을 고객에게 안내한 후 계속 진행하세요.

book 토큰은 단일 사용(single-use) 입니다. 한 번 사용하면 재사용할 수 없으므로, 예약 실패 시 Step 1부터 다시 시작해야 합니다.


Step 3: 예약 생성

POST /api/channel/v2/bookings?token=

Step 2에서 발급된 book 토큰과 투숙객 정보로 예약을 생성합니다.

쿼리 파라미터

파라미터설명
tokenStep 2에서 발급된 book 토큰 (단일 객실 예약 시)

요청 바디

필드필수설명
rooms투숙객 정보 배열
rooms[].given_name투숙객 이름
rooms[].family_name투숙객 성
affiliate_reference_id-채널 자체 예약 참조 ID
book_tokens-복수 객실 예약 시 book 토큰 배열 (query의 token 대신 사용)

Step 3: 예약 생성

응답 (201 Created)

{
  "itinerary_id": "ONDA1743500000000",
  "links": {
    "retrieve": {
      "method": "GET",
      "href": "/api/channel/v2/bookings/retrieve?token=eyJ...",
      "expires": "2027-04-01T10:00:00.000Z"
    },
    "cancel": {
      "method": "PUT",
      "href": "/api/channel/v2/bookings/cancel?token=eyJ...",
      "expires": "2027-04-01T10:00:00.000Z"
    }
  }
}

itinerary_idretrieve/cancel 링크를 안전하게 저장하세요. 예약 조회와 취소에 사용됩니다.


Step 4a: 예약 조회

GET /api/channel/v2/bookings/retrieve?token=

예약 생성 응답의 retrieve 링크를 호출하여 예약 상세를 조회합니다.

Step 4a: 예약 조회

응답 구조

{
  "itinerary_id": "ONDA1743500000000",
  "status": "confirmed",
  "property_id": "12345",
  "checkin": "2026-04-01",
  "checkout": "2026-04-03",
  "request_currency": "KRW",
  "billable_currency": "KRW",
  "rooms": [
    {
      "room_id": "a1b2c3d4",
      "rate_id": "e5f6g7h8",
      "bed_group_id": "37321",
      "bed_group_description": "1 King Bed",
      "status": "confirmed",
      "refundable": true,
      "guest": {
        "given_name": "길동",
        "family_name": "홍"
      },
      "occupancy_pricing": { ... },
      "cancel_penalties": [],
      "cancel_refund": {
        "refundable": true,
        "refund_amount": 330000,
        "penalty_amount": 0,
        "currency": "KRW"
      }
    }
  ],
  "links": {
    "cancel": {
      "method": "PUT",
      "href": "/api/channel/v2/bookings/cancel?token=eyJ...",
      "expires": "2027-04-01T10:00:00.000Z"
    }
  }
}

Step 4b: 예약 취소

PUT /api/channel/v2/bookings/cancel?token=

예약 생성(또는 조회) 응답의 cancel 링크를 호출하여 예약을 취소합니다.

cancel 토큰은 단일 사용(single-use) 입니다. 취소 요청이 성공하면 토큰이 소진됩니다. 취소 후 조회가 필요하면 retrieve 토큰을 별도로 저장해두세요.

Step 4b: 예약 취소

응답 구조

{
  "itinerary_id": "ONDA1743500000000",
  "status": "cancelled",
  "cancel_refund": {
    "refundable": true,
    "refund_amount": 330000,
    "penalty_amount": 0,
    "currency": "KRW"
  }
}

콘텐츠 API

숙소 목록 조회

GET /api/channel/v2/properties

연동된 숙소 목록을 페이지 토큰 기반으로 조회합니다.

쿼리 파라미터

파라미터설명
page_token다음 페이지 토큰 (첫 페이지는 생략)
per_page페이지당 결과 수
updated_since해당 시각 이후 변경된 숙소만 조회 (ISO 8601)
curl -X GET "https://developers.tport.dev/api/channel/v2/properties?per_page=20" \
  -H "X-Api-Key: {your_api_key}"

숙소 상세 조회

GET /api/channel/v2/properties/{id}

특정 숙소의 상세 정보를 조회합니다. property_id는 문자열로 반환됩니다.

curl -X GET "https://developers.tport.dev/api/channel/v2/properties/12345" \
  -H "X-Api-Key: {your_api_key}"

객실 타입 목록 조회

GET /api/channel/v2/properties/{id}/roomtypes

특정 숙소의 객실 타입 목록을 조회합니다.

curl -X GET "https://developers.tport.dev/api/channel/v2/properties/12345/roomtypes" \
  -H "X-Api-Key: {your_api_key}"

토큰 오류 처리

v2 API는 단계 간 연결에 토큰을 사용합니다. 토큰 관련 오류 시나리오와 대응 방법입니다.

HTTP 상태오류 코드원인대응
400INVALID_TOKEN토큰 형식 오류 또는 타입 불일치Step 1부터 재시작
409TOKEN_ALREADY_USED단일 사용 토큰을 재사용 시도Step 1부터 재시작
410TOKEN_EXPIRED토큰 유효 기간 초과Step 1부터 재시작
403FORBIDDEN경로 파라미터가 토큰 컨텍스트와 불일치href를 그대로 사용

토큰 오류(4xx)가 발생하면 항상 Step 1(가용성 검색)부터 다시 시작하세요. 중간 단계부터 재시도하는 것은 지원하지 않습니다.


v1에서 v2로 마이그레이션

1. 예약 흐름 재구성

v1은 직접 파라미터를 조합하여 예약 API를 호출하는 방식이었습니다. v2는 응답의 링크(href)를 따라가는 방식입니다.

v1: GET /search/availability → GET /search/price-check → POST /bookings

v2: GET /properties/availability (price_check 링크 수령)
    → GET /properties/{pId}/rooms/{rId}/rates/{rateId}?token= (book 링크 수령)
    → POST /bookings?token= (retrieve/cancel 링크 수령)

2. property_id 형식 변경

v2에서 property_id는 항상 문자열로 반환됩니다. 숫자로 비교하거나 저장하지 마세요.

// v1 (숫자)
property.property_id === 12345

// v2 (문자열)
property.property_id === "12345"

3. 인원 파라미터 변경

v1의 adults/children 파라미터 대신 EPS 호환 occupancy 파라미터를 사용합니다.

v1: ?adults=2&children=1
v2: ?occupancy=2-5   (성인 2명, 어린이 5세 1명)

4. room/rate ID 변경

v2의 room ID와 rate ID는 내부 ID를 해싱한 값입니다. 직접 생성하거나 저장하지 말고 가용성 검색 응답에서 가져오세요.


다음 단계