<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[metasearch]]></title><description><![CDATA[Source-backed travel metasearch and distribution engineering content for developers, including hotel feed validation, platform integrations, open-source tools, MCP workflows, architecture and troubleshooting.]]></description><link>https://metasearch.hashnode.dev</link><image><url>https://cdn.hashnode.com/uploads/logos/6ac9340c88e00ba70c5c1137/6a111075-826b-43f8-b3a7-79738f220acf.png</url><title>metasearch</title><link>https://metasearch.hashnode.dev</link></image><generator>RSS for Node</generator><lastBuildDate>Wed, 14 Oct 2026 06:44:52 GMT</lastBuildDate><atom:link href="https://metasearch.hashnode.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[One hotel feed, three metasearch validation targets]]></title><description><![CDATA[A hotel feed is not simply “valid” or “invalid.”
In travel distribution, validity depends on the destination.
The same supplier dataset can look complete internally and still require different fields,]]></description><link>https://metasearch.hashnode.dev/one-hotel-feed-three-metasearch-validation-targets</link><guid isPermaLink="true">https://metasearch.hashnode.dev/one-hotel-feed-three-metasearch-validation-targets</guid><category><![CDATA[travel tech]]></category><category><![CDATA[Open Source]]></category><category><![CDATA[Devops]]></category><category><![CDATA[metasearch]]></category><dc:creator><![CDATA[Gökhan Kurt]]></dc:creator><pubDate>Fri, 09 Oct 2026 19:36:34 GMT</pubDate><content:encoded><![CDATA[<p>A hotel feed is not simply “valid” or “invalid.”</p>
<p>In travel distribution, validity depends on the destination.</p>
<p>The same supplier dataset can look complete internally and still require different fields, mappings, or checks for Google Hotel Center, Wego, or trivago.</p>
<p>That is why I ended up separating two concerns in <a href="https://github.com/metasearchcomtr/feed-validator"><code>@metasearch/feed-validator</code></a>:</p>
<ol>
<li><strong>canonical hotel normalization</strong></li>
<li><strong>platform-specific validation</strong></li>
</ol>
<p>Those two layers solve different problems, and mixing them creates false confidence.</p>
<h2>Start with a canonical hotel model</h2>
<p>Supplier feeds rarely agree on field names.</p>
<p>One source may send:</p>
<pre><code class="language-json">{
  "hotel_id": "TR-IST-001",
  "hotel_name": "Example Hotel",
  "country_code": "TR",
  "lat": 41.038,
  "lng": 28.986
}
</code></pre>
<p>Another may send:</p>
<pre><code class="language-json">{
  "property_id": "TR-IST-001",
  "name": "Example Hotel",
  "country": "TR",
  "latitude": 41.038,
  "longitude": 28.986
}
</code></pre>
<p>For internal processing, both records can be normalized into a shared model:</p>
<pre><code class="language-ts">type CanonicalHotel = {
  id?: unknown
  name?: unknown
  description?: unknown
  address?: unknown
  city?: unknown
  province?: unknown
  postalCode?: unknown
  country?: unknown
  phone?: unknown
  latitude?: unknown
  longitude?: unknown
  link?: unknown
  image?: unknown
  brand?: unknown
  category?: unknown
  starRating?: unknown
  amenities?: unknown
}
</code></pre>
<p>That canonical layer is useful for mapping, comparison, observability, and downstream processing.</p>
<p>But it is <strong>not</strong> a platform contract.</p>
<h2>Why one universal validator is misleading</h2>
<p>It is tempting to create a generic score like:</p>
<blockquote>
<p>“This hotel feed is 92% valid.”</p>
</blockquote>
<p>But valid for what?</p>
<p>Google Hotel Center, Wego, and trivago do not expose identical hotel-data contracts.</p>
<p>A single generic score can hide the exact differences an integration engineer needs to see.</p>
<p>Instead, the validator keeps common parsing and normalization shared while applying destination-specific rule packs afterward.</p>
<p>You can run the same feed through several targets:</p>
<pre><code class="language-bash">npx @metasearch/feed-validator compare hotels.csv \
  --targets google-hotel-center,wego,trivago
</code></pre>
<p>The useful question becomes:</p>
<blockquote>
<p>What is missing for each destination?</p>
</blockquote>
<p>rather than:</p>
<blockquote>
<p>Is this feed globally valid?</p>
</blockquote>
<h2>Published-contract validation vs readiness checks</h2>
<p>There is another distinction that matters: <strong>evidence quality</strong>.</p>
<p>The project currently treats Google Hotel Center, Wego, and trivago as published-contract validation targets because their implemented checks are based on maintainable first-party technical requirements.</p>
<p>Meta and Criteo are handled differently.</p>
<p>Those are explicitly labeled <strong>readiness checks</strong>, not certification.</p>
<p>That distinction is deliberate.</p>
<p>If the public technical contract is insufficient for a true validator, the tool should not invent undocumented mandatory fields just to make the interface look complete.</p>
<p>A developer tool should expose uncertainty instead of hiding it.</p>
<h2>Same input, different target semantics</h2>
<p>For example, the same synthetic hotel feed can be checked independently:</p>
<pre><code class="language-bash">npx @metasearch/feed-validator validate examples/hotels.csv \
  --target google-hotel-center
</code></pre>
<pre><code class="language-bash">npx @metasearch/feed-validator validate examples/hotels.csv \
  --target wego
</code></pre>
<pre><code class="language-bash">npx @metasearch/feed-validator validate examples/hotels.csv \
  --target trivago
</code></pre>
<p>This makes target-specific gaps visible before partner onboarding or feed delivery.</p>
<p>The repository includes synthetic CSV and JSON examples so the workflow can be reproduced without production hotel data.</p>
<h2>CI is where this becomes useful</h2>
<p>Feed validation is most valuable before a partner receives a broken payload.</p>
<p>For example, a pull-request workflow can fail when a feed violates the configured threshold:</p>
<pre><code class="language-yaml">name: Validate hotel feed

on:
  pull_request:

jobs:
  validate-feed:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v5

      - uses: actions/setup-node@v5
        with:
          node-version: 22

      - run: &gt;
          npx @metasearch/feed-validator
          validate path/to/hotels.csv
          --target google-hotel-center
          --fail-on error
</code></pre>
<p>The CLI uses deterministic exit codes:</p>
<ul>
<li><code>0</code> — validation passed</li>
<li><code>1</code> — configured validation threshold failed</li>
<li><code>2</code> — input, fetch, parsing, or CLI error</li>
</ul>
<p>For machine-readable pipelines:</p>
<pre><code class="language-bash">npx @metasearch/feed-validator validate hotels.csv \
  --target google-hotel-center \
  --output json
</code></pre>
<h2>One engine, several interfaces</h2>
<p>The same validation model is exposed through several surfaces:</p>
<ul>
<li>CLI</li>
<li>Node.js SDK</li>
<li>browser validator</li>
<li>remote MCP server</li>
</ul>
<p>The <a href="https://metasearch.com.tr/en/tools/hotel-feed-validator?utm_source=hashnode&amp;utm_medium=article&amp;utm_campaign=feed-validator-launch-2026&amp;utm_content=architecture">browser validator</a> is useful for quick inspection.</p>
<p>The <a href="https://metasearch.com.tr/en/mcp?utm_source=hashnode&amp;utm_medium=article&amp;utm_campaign=mcp-launch-2026&amp;utm_content=architecture">remote MCP server</a> exposes the same concepts to MCP-compatible clients.</p>
<p>That makes a workflow like this possible:</p>
<blockquote>
<p>Detect the feed format, normalize the hotel records, compare Google Hotel Center, Wego and trivago requirements, validate each target, and explain the remediation steps.</p>
</blockquote>
<p>The MCP server currently exposes 12 tools covering format detection, normalization, validation, platform comparison, and deterministic fix suggestions.</p>
<h2>The architectural boundary matters</h2>
<p>The important lesson is not specific to hotel feeds.</p>
<p>Canonicalization and validation are separate layers.</p>
<p><strong>Canonicalization asks:</strong></p>
<blockquote>
<p>How can heterogeneous source records be represented consistently?</p>
</blockquote>
<p><strong>Validation asks:</strong></p>
<blockquote>
<p>Does this normalized data satisfy the contract of a specific destination?</p>
</blockquote>
<p>When those layers are kept separate:</p>
<ul>
<li>supplier aliases stay out of platform rule logic,</li>
<li>platform requirements do not pollute the canonical model,</li>
<li>validation can evolve independently per destination,</li>
<li>unsupported assumptions are easier to identify,</li>
<li>CI failures become easier to explain.</li>
</ul>
<p>That separation is especially useful in travel distribution, where one supplier feed may eventually be mapped to several metasearch, OTA, catalog, or channel destinations.</p>
<h2>Open source</h2>
<p>The implementation, synthetic sample feeds, and CI examples are available in the open-source <a href="https://github.com/metasearchcomtr/feed-validator"><code>metasearchcomtr/feed-validator</code></a> repository.</p>
<p>There is also a <a href="https://metasearch.com.tr/en/compare/hotel-feed-requirements?utm_source=hashnode&amp;utm_medium=article&amp;utm_campaign=feed-validator-launch-2026&amp;utm_content=comparison">hotel feed requirements comparison</a> if you want to inspect the supported targets side by side.</p>
<p>I would be interested in hearing how other travel-tech teams separate normalization, mapping, and validation in their distribution pipelines.</p>
]]></content:encoded></item></channel></rss>