Resolving Viator API Integration: When Certified Partners Are Your Only Option
During a recent integration audit, we discovered a critical gap in our Viator supplier connectivity: their API documentation promises programmatic calendar sync, but the actual implementation requires routing through a certified channel manager. This post walks through the technical investigation, the constraints we hit, and the architectural decision we made to move forward.
The Problem: API Documentation vs. Reality
Our system was attempting to maintain real-time availability sync between our booking database and Viator's supplier dashboard (product ID 5653407P1 — Private Yacht Charters on Jada The Queen of San Diego). We assumed Viator exposed either:
- A direct REST API endpoint for supplier calendar updates
- An iCal feed we could poll directly from their system
- Webhook support for booking confirmations
The technical contact at Viator (James Jimenez, API team) confirmed none of these exist as public, self-serve options. Their actual architecture requires suppliers to connect through their dashboard's Account Settings → Connectivity → Connect Now panel, which only accepts certified integration partners.
Technical Investigation: Email-Based Thread Analysis
We traced this through our support ticket system (t-ad4b92d7) by reading the IMAP message thread directly from our operations email (jadasailing@gmail.com). The investigation revealed:
# Commands used to audit the integration state:
# Check available mail utilities
which mail mailx sendmail
# IMAP connection via Gmail app password (stored in .env)
# Reading message 11124 from Viator API team
# Searching for related connectivity responses:
grep -r "certified.*partner" ./ticket-archives/
grep -r "iCal\|webhook\|direct.*api" ./viator-docs/
Viator's response confirmed their architecture: they maintain a whitelist of certified partners in their viator.com/connectivity/ directory. Suppliers cannot bypass this integration layer.
The Constraint: Free vs. Paid Channel Managers
The discovery created an architectural constraint: every certified connectivity partner we evaluated falls into one of two categories:
- Paid Channel Managers (Bókun, Rezdy, etc.): They take a percentage fee (6-8%) on each booking routed through them. These are rejected per business requirements.
- Free Integrations: FareHarbor is the only certified partner that doesn't charge operators. They monetize by taking a small guest-facing fee (~6%) but don't assess supplier fees.
We were already connected to Bókun via their Viator integration, which created a secondary problem: the system showed Status: Connected (to Bókun) in the Product connection tab, meaning calendar updates were potentially routing through their system with associated fees.
Immediate Tactical Fix: Manual Availability Blocking
While evaluating long-term solutions, we needed to manually block May 30 to prevent overbooking. The process:
- Navigate to
supplier.viator.com(supplier dashboard) - Locate product 5653407P1 in the product listing
- Access the Availability or Manage Availability tab
- Locate May 30 on the calendar view
- Click the date and select Blocked or Unavailable
- Confirm and save
The dashboard showed "Availability updated automatically" messages, indicating a sync process was active — likely the iCal feed we'd configured through Google Calendar. However, there was a propagation lag: changes we made in Google Calendar weren't immediately reflected in Viator's system, requiring manual intervention.
Disconnecting the Bókun Channel: Reducing Fee Exposure
To stop unintended fee charges, we disconnected the Bókun integration from the Viator product connection:
- In
supplier.viator.com, opened the Product connection tab - Located the Bókun connection showing Status: Connected
- Clicked the Edit button (top-right of the connection panel)
- Selected Remove or Disconnect
- Confirmed the removal
This eliminated the automatic fee charge but left us without real-time sync until we selected a new integration path.
Architectural Decision: FareHarbor as the Integration Layer
Given the constraints, FareHarbor emerged as the only viable option that aligns with business requirements:
- Certified Partner: Viator's whitelist includes FareHarbor (viator.com/connectivity/farehabor)
- No Operator Fees: They don't charge suppliers; monetization comes from guest-facing optional insurance/fees
- Bidirectional Sync: FareHarbor maintains real-time calendar sync with Viator's backend via their certified integration
- Webhook Support: FareHarbor's API (v2, endpoint
api.farehabor.com/external/v2/) exposes webhooks for booking events
The integration flow would be:
Our Booking System
→ FareHarbor API (POST to /bookings)
→ FareHarbor → Viator (via certified connector)
→ Viator Supplier Dashboard (product 5653407P1)
Reverse flow:
Viator Booking → FareHarbor webhook → Our System (/webhooks/farehabor/events)
Critical Follow-Up: The iCal Question
Before committing to FareHarbor's fee structure (even if supplier-side is free), we sent a follow-up to James Jimenez asking a more specific technical question:
Does Viator expose an iCal URL for confirmed supplier bookings that
we could poll directly from your API, without routing through a
certified partner?
This was worth asking because some suppliers publish undocumented iCal feeds that can be discovered through their backend. If such a feed exists at (for example) api.viator.com/suppliers/{id}/calendar.ics, we could bypass the partner requirement entirely.
What's Next: Integration Implementation
Pending James's response, our implementation roadmap is:
- If iCal feed exists: Implement a polling Lambda function (triggered every 15 minutes via CloudWatch Events) that fetches the feed from Viator's API and reconciles it with our booking state
- If no iCal: Proceed with FareHarbor integration by connecting the product via their dashboard connector, then implement bidirectional sync via their REST API and webhook handlers
Either path requires updating our supplier state machine in lib/suppliers/viator.py to handle the new sync source, updating our webhook route handlers, and adding corresponding test cases for availability reconciliation.