Making two systems agree on one number
Product, price and availability usually live in more than one place. This is the work of deciding which copy is true, moving it reliably, and exposing it to partners in a form they can build on without calling you every week.
What actually moves between systems
"Sync the data" is four different jobs with four different tolerances. Treating them as one is why so many integrations feel almost right and are never trusted.
| Data | How often it changes | What happens when it is stale |
|---|---|---|
| Product — name, description, images | Rarely | Embarrassing, not expensive. A nightly push is fine |
| Price — season, per-person tiers, options | Weekly to seasonally | You honour a price you did not intend to sell |
| Availability — seats, cabins, departures | Constantly | You sell something that does not exist |
| Bookings and customers | Per transaction | Two systems disagree about who is arriving on Friday |
Availability is the only one of the four that genuinely needs to be near real-time. Half the integration budgets we see are spent making product descriptions update instantly while the seat count is still hours behind.
Source data quality decides the timeline
The uncomfortable truth of this work: the code is rarely the long part. A tour catalogue kept in a spreadsheet with inconsistent naming will cost more days than the entire integration built on top of it.
A real example of what a catalogue looks like on the first day. Three rows read "Ha Long Bay 2D1N", "HaLong 2 days 1 night" and "Halong Bay - 2D1N (New)". They are one product, two products or three depending on who you ask in the office. The price column contains both USD and VND, sometimes in the same cell. A column called Notes holds actual business rules — "child under 5 free but not in Nov" — that no system will ever read.
- Freeze the sheet. Work from one dated export, not from a file people are still editing while we map it.
- Produce a catalogue where every product has a stable identifier that never changes, even when the marketing name does.
- Put every ambiguous row in front of a person who can decide, and record the decision next to it.
- Move the business rules out of free text and into fields, or accept that they stay manual and say so in writing.
We ask for the real export before quoting. A clean catalogue and a messy catalogue of the same size are not the same project, and pretending otherwise only moves the bad news to week six.
Matching products across two systems
When the same tours exist in your system and in a partner's, something has to decide which row is which. Automatic matching is useful and dangerous in the same breath: a wrong merge overwrites a price, and nobody notices until a guest pays the wrong amount.
We match in bands rather than with a single yes or no, and the bands are agreed with you before anything is written.
| Confidence | What we do | Why |
|---|---|---|
| Exact code or supplier reference matches | Link automatically | This is the only truly safe case |
| Strong name and duration similarity | Link, but flag for review | Usually right, occasionally two departures of different length |
| Partial similarity | Human queue, nothing written | A person decides in seconds what an algorithm gets wrong for months |
| No match | Create as new, marked unverified | Better a duplicate you can see than a silent overwrite |
The rule underneath all of it: an automated process may create and it may propose, but it does not silently merge two things that were previously separate.
Giving partners an API
Publishing an API is a promise, and the day someone builds against it you have lost the freedom to change it casually. Before a single partner is given a key, there are things you have to commit to.
- A version in the URL or the header, and a rule for what a new version means. Adding a field is not a new version. Renaming or removing one always is.
- A rate limit, published, with a clear error when it is hit. Without it your first enthusiastic partner becomes an outage.
- An error format that stays the same everywhere, so a partner can write one handler instead of guessing.
- A deprecation notice period you will actually honour, written down before anyone depends on you.
- A sandbox with data that looks like production, and keys that can be rotated without a phone call.
- A changelog. Partners forgive changes; they do not forgive surprises.
One design decision is worth more than all of those: do not expose your database shape. The API is a contract about travel products, not a window into your tables. The day you restructure internally, that separation is what lets you do it without breaking every partner at once.
Log first, then call out
Under2 has one rule that appears in every integration we build, including the enquiry form on this website. When data arrives from a customer, it is written to disk locally before any outbound call is made. Only then do we push it onward — on this site, to a Lark webhook and to email through Mailgun.
The reason is simple. Networks fail, third-party services return errors at exactly the wrong moment, and an API key expires on a Saturday. If the outbound call is the first thing that happens, a failure means the customer's request is gone and nobody knows it existed. If the write happens first, the worst case is a delay and a retry.
- Every outbound call carries an idempotency key, so a retry cannot create a second booking.
- Retries back off rather than hammering a service that is already struggling.
- Incoming webhooks are de-duplicated, because every serious platform will send you the same event twice eventually.
- Failed deliveries stay in a queue that a human can see and replay, not in a log file nobody opens.
Because it is the difference between losing an enquiry and delaying one, and because it costs nothing to build in at the start and a great deal to retrofit after the first lost booking.
When a nightly CSV is the right answer
Not every exchange deserves an API. A file dropped once a night is easier to build, easier to audit and far easier for a partner's IT team to consume, and for several kinds of travel data it is genuinely the correct choice.
- The data changes daily at most — a product catalogue, a seasonal rate sheet, a commission schedule.
- The partner cannot consume an API. A tour operator's accountant with a spreadsheet is a real constraint, not a failure of ambition.
- You need to see exactly what was sent on a given day. A dated file is its own audit trail; an API call is not, unless you built the logging for it.
- The volume is small enough that the whole set can be sent, which removes an entire category of bug about what changed since last time.
The one field that almost never belongs in a nightly file is availability. If a partner is selling your seats from a file that is up to twenty-four hours old, you are choosing to oversell. That is a commercial decision, and it should be made with the number in front of you rather than by accident.
What we do not take on
- Data work outside travel. We know what a tour product is; we do not know your industry's edge cases and would be charging you to learn them.
- An API on top of data the business does not control or has not cleaned. We will quote the cleanup first and the API second, in that order.
- Scraping a competitor's site or a marketplace to fake an integration. It breaks on their next release and it puts your account at risk.
- A one-way sync described to your partners as two-way. If bookings do not flow back, that is written in the documentation in plain words.
Send us the export
The real spreadsheet or a sample of the feed, and what it has to talk to. We will tell you what is clean, what is not, and what that means for the schedule.
What travel operators ask us most
How fast can availability sync be?
Near real-time is achievable when both systems support webhooks or a push mechanism. When one side only offers polling, the honest answer is that your freshness equals your polling interval plus the queue, and we design the overselling rules around that number instead of hiding it.
We always agree what happens in the gap before we build, because that gap is where double bookings live.
Can you integrate with a system that has no API?
Sometimes, through file exchange, a database replica or an export the vendor already produces. What we will not do is drive a user interface with a script and call it an integration.
If no supported path exists, that is a finding worth having early — it usually changes which system you keep.
Who owns the data mapping once the project ends?
You do. The mapping, the identifiers and the transformation rules are handed over as documentation, not kept as leverage.
This matters more than the code. Rewriting an integration is a few weeks; rediscovering which product is which takes months.
Do you build partner APIs for companies you did not build the system for?
Yes, provided we can read the existing data model and there is someone on your side who can answer questions about it.
We will read it before quoting and we charge for that reading, because a free assessment always conveniently concludes that a rebuild is needed.
Read next
Tell us what you are trying to run
What you sell, what you use today, and what is breaking. You get a written answer with an approach and a price range - not a brochure.