Why Hotel API Integration is So Hard? (1) Authentication Nightmare: 10-Week Plan, 24 Weeks and Still Not Done
The first nightmare of hotel API integration: authentication. 5 suppliers, 5 different authentication methods - Basic Auth, HMAC-SHA256, OAuth1, JWT... A 10-week plan, 24 weeks and still not done with the first supplier.
3 years ago, I received a task: integrate 5 hotel supplier APIs to allow users to search global hotel inventory.
I thought: 5 REST APIs, 2 weeks each, total 10 weeks, done.
10 weeks later, I was still debugging authentication issues with the first supplier.
2 years later, I quit, and the project still wasn’t fully launched.
The Initial Misunderstanding
My Plan (Week 1)
Week 1-2: HotelBeds API Integration
Week 3-4: Dida API Integration
Week 5-6: DerbySoft API Integration
Week 7-8: Expedia API Integration
Week 9-10: Agoda API Integration
Week 11-12: Testing & Launch
Reality (Week 24)
Week 1-4: HotelBeds - Authentication Failed
Week 5-8: HotelBeds - Data Format Inconsistency
Week 9-12: HotelBeds - Rate Limiting Issues
Week 13-16: Dida - Signature Algorithm Error
Week 17-20: Dida - Timezone Issues
Week 21-24: DerbySoft - Not Started Yet
I underestimated the complexity of hotel APIs.
First Challenge: Authentication Hell
Supplier A: Basic Auth (Simple)
GET /api/hotels?destination=London
Authorization: Basic YXBpX2tleTphcGlfc2VjcmV0
Problem: No problem, 5 minutes done.
Supplier B: HMAC-SHA256 (Starting to Get Headaches)
Documentation says:
Signature = HMAC-SHA256(
API_SECRET,
HTTP_METHOD + "\n" +
REQUEST_PATH + "\n" +
TIMESTAMP + "\n" +
NONCE + "\n" +
REQUEST_BODY
)
My Implementation:
func GenerateSignature(apiKey, apiSecret, method, path, body string) string {
timestamp := fmt.Sprintf("%d", time.Now().Unix())
nonce := generateNonce()
payload := fmt.Sprintf("%s\n%s\n%s\n%s\n%s",
method, path, timestamp, nonce, body)
h := hmac.New(sha256.New, []byte(apiSecret))
h.Write([]byte(payload))
return hex.EncodeToString(h.Sum(nil))
}
Result: 401 Unauthorized.
Debug Process:
- ❌ Check API Secret - Correct
- ❌ Check HMAC algorithm - Correct
- ❌ Check payload format - Correct
- ❌ Check timestamp - Correct
- ❌ Check nonce - Correct
- ✅ Discovery: Documentation didn’t say to URL encode the payload!
Fix:
payload := url.QueryEscape(fmt.Sprintf("%s\n%s\n%s\n%s\n%s",
method, path, timestamp, nonce, body))
Time taken: 3 days
Lesson: Never trust API documentation completely.
Supplier C: OAuth1 (Nightmare Begins)
Documentation: 200 pages, mostly废话, key information hidden on page 147.
OAuth1 Flow:
- Get temporary Token
- Exchange temporary Token for Access Token
- Use Access Token to call API
- Access Token expires after 1 hour
My Implementation:
func GetAccessToken() (string, error) {
// Step 1: Get temporary Token
reqToken, err := oauth1.GetRequestToken()
if err != nil {
return "", err
}
// Step 2: Authorize (requires user browser operation, backend can't automate)
// ❌ Stuck here
// Step 3: Exchange for Access Token
accessToken, err := oauth1.GetAccessToken(reqToken, verifier)
if err != nil {
return "", err
}
return accessToken, nil
}
Problem: OAuth1 is designed for user authorization, not machine-to-machine. But this supplier insists on using OAuth1.
Solution: Communicated with supplier technical support, they gave a “backend authentication” API, but it’s not in the documentation.
Time taken: 2 weeks (most time waiting for supplier response)
Final Results
24 weeks later, I finally integrated 5 suppliers:
| Supplier | Estimated Time | Actual Time | Delay Reason |
|---|---|---|---|
| HotelBeds | 2 weeks | 16 weeks | Authentication, rate limiting, error handling |
| Dida | 2 weeks | 6 weeks | Signature, timezone |
| DerbySoft | 2 weeks | 2 weeks | Relatively simple |
| Expedia | 2 weeks | Not completed | Incomplete documentation, gave up |
| Agoda | 2 weeks | Not completed | Can’t reach technical support |
Total:
- Estimated: 10 weeks
- Actual: 24 weeks (and not completed)
- Delay: 140%
If I Could Do It Again
Option 1: Use Existing Aggregation Platform
- Pros: Quick integration (1-2 weeks)
- Cons: Need to pay commission, high cost
- Cost: $500,000+ / year
Option 2: Build It Yourself, But Use SDK
- Pros: Control cost, quick integration (4-8 weeks)
- Cons: Need technical team
- Cost: $50,000 - $100,000 (development) + $5,000 / month (subscription)
Our Solution:
- Provide multi-language SDKs (Go, Java, Python, JavaScript)
- Unified authentication (one API Key)
- Unified data format (Hotel/Room/RatePlan)
- Smart retry (automatically handle rate limiting, timeouts)
- Detailed documentation and example code
Quick Start (5 minutes):
// Install
go get github.com/hotelbyte-com/sdk-go
// Initialize
client := hotelbyte.NewClient(
hotelbyte.WithCredentials("your-api-key", "your-api-secret"),
hotelbyte.WithBaseURL("https://api.hotelbyte.com"),
)
// Search
resp, err := client.SearchHotels(ctx, &hotelbyte.SearchHotelsRequest{
DestinationID: "LHR",
CheckIn: time.Now().AddDate(0, 0, 7),
CheckOut: time.Now().AddDate(0, 0, 9),
AdultCount: 2,
RoomCount: 1,
})
// Done!
fmt.Printf("Found %d hotels\n", len(resp.Hotels))
Summary
3 Reasons Why Hotel API Integration is Hard:
- Authentication Hell: Basic Auth → HMAC → OAuth1 → Custom signature
- Data Chaos: Field naming, time formats, price formats all different
- Unpredictability: Rate limiting, error handling, timezone issues
If you only have 1-2 suppliers:
- Building it yourself is acceptable (but watch your time budget)
If you have 5+ suppliers:
- Use SDK or aggregation platform (save time + reduce cost)
If you have 50+ suppliers:
- Must use aggregation platform (otherwise your technical team will explode)
Recommended Resources
Open Source SDKs:
- Go SDK: github.com/hotelbyte-com/sdk-go
- Java SDK: github.com/hotelbyte-com/sdk-java
Technical Documentation:
Join Us:
- GitHub: github.com/hotelbyte-com
- Product: waitlist.hotelbyte.com
Comments