Travel fare aggregation proxies
Travel fares and hotel rates by point of sale: collect publicly listed flight fares and hotel rates as each market sees them, with a sticky session for every search sequence.
Proxy URL, exit IP in United Kingdom
http://USERNAME-cc-GB-session-a1b2c3d4-ttl-30:PASSWORD@scale-eu.netdash.io:2000Residential exit IPs in United Kingdom
Illustrative routes, not live traffic. Exits are available in most countries; the countries shown are examples.
- Country-level targeting by ISO code
- Sticky sessions with a TTL in minutes
- Purchased GB never expire
Why fare data depends on the point of sale
Flight fares and hotel rates are published per point of sale, in that market’s currency and with its fees, and they change through the day. A collector that runs in one location records one market’s prices for every market it checks.
Travel fare aggregation proxies give each search an exit IP in the point of sale you analyze. In netdash the point of sale is the -cc- code in the proxy username, and a sticky session carries a search, its results and the detail pages on one exit IP. The goal is comparable market data: another exit country shows that market’s published prices, not a cheaper version of them.
Point of sale, currency and the exit country
| Attribute | What varies | How to handle it in your collection |
|---|---|---|
| Point of sale | Which market’s prices and offers the site shows | Set by the exit country |
| Currency | The currency prices are listed in | Set the site’s public currency selector once per session; store the raw amount with its currency |
| Taxes and fees display | Whether listed prices include taxes and fees | Store a taxes-included flag with each price |
| Market-specific offers | Fares or rates offered only in some markets | Set by the exit country; record it with each price |
| Search session state | Results and detail pages that depend on the search | One sticky session and one cookie jar per search sequence |
A fare collection run
Step 1: Define the matrix
Routes or properties × travel dates × points of sale.
Step 2: Check the source’s terms
Prefer official APIs, affiliate feeds or data partnerships where they exist.
Step 3: Open a session per sequence
Exit country = point of sale, sticky
Sticky sessions30, one cookie jar. Set the site’s public market and currency selector once.Step 4: Search, then read results and details
In that order, on the same session.
Step 5: Store raw values with context
The data model below keeps markets comparable.
Step 6: Pace the run
Spread searches across the day within each site’s limits. Keep collection read-only: no bookings or account actions.
Search sequences need one exit IP
A search, its results and the detail pages often depend on state set when the search starts. Keep the whole sequence on one sticky session and one cookie jar. The proxy string format explains each part of the username.
- Plan and endpoint
Scale ·
scale-eu.netdash.io:2000for a GB point of salescale-us.netdash.io:2000for a US point of sale. Every residential plan uses the same syntax; you switch plans by changing the host and port.- Username
USERNAME-cc-GB-session-{SID}-ttl-30The password is the proxy password from the dashboard, not your sign-in password.
- Session mode and TTL
Sticky,
30minutes per search sequenceThe sequence stays on one exit IP while it remains available. Dashboard presets run from 15 minutes to 7 days.
- Session ID
First 8 hex characters of a hash of site, market, route and date
One per sequence, and reproducible from its inputs.
- Client
One
requests.Sessionper sequenceIts cookie jar carries the site’s state from search to detail page.
Build the username for one point of sale
Pick the point of sale you analyze. The builder starts with the GB point of sale from the example above, through the Europe gateway.
Your route
Through the gateway to an exit IP in , , on the plan.
Proxy URL
http://USERNAME-cc-GB-session-a1b2c3d4-ttl-30:PASSWORD@scale-eu.netdash.io:2000Replace USERNAME and PASSWORD with the credentials from your dashboard.
Scale, Europe gateway, exit IP in United Kingdom, sticky for 30 min.
curl --max-time 30 -x "http://USERNAME-cc-GB-session-a1b2c3d4-ttl-30:PASSWORD@scale-eu.netdash.io:2000" \
"https://api.ipify.org?format=json"import requests
proxy = "http://USERNAME-cc-GB-session-a1b2c3d4-ttl-30:PASSWORD@scale-eu.netdash.io:2000"
proxies = {"http": proxy, "https": proxy} # set both, or HTTPS requests bypass the proxy
response = requests.get("https://api.ipify.org?format=json", proxies=proxies, timeout=30)
response.raise_for_status()
print(response.text)import { ProxyAgent, fetch } from "undici";
const dispatcher = new ProxyAgent({
uri: "http://scale-eu.netdash.io:2000",
token: "Basic " + Buffer.from("USERNAME-cc-GB-session-a1b2c3d4-ttl-30:PASSWORD").toString("base64"),
});
const res = await fetch("https://api.ipify.org?format=json", { dispatcher, signal: AbortSignal.timeout(30_000) });
console.log(await res.text());import { chromium } from "playwright";
const browser = await chromium.launch({
proxy: {
server: "http://scale-eu.netdash.io:2000",
username: "USERNAME-cc-GB-session-a1b2c3d4-ttl-30",
password: "PASSWORD",
},
});
const page = await browser.newPage();
await page.goto("https://api.ipify.org?format=json");
console.log(await page.textContent("body"));
await browser.close();Example output
{"ip":"203.0.113.10"}Your output shows a different address in the country you chose.
A search sequence on one session
One requests.Session per search sequence keeps the site’s cookies, and the sticky session ID, derived from site, market, route and date, keeps the three calls on one exit IP. The proxy goes into proxies on every call with both http and https keys: the requests documentation notes that session-level proxies can be overwritten by proxy environment variables.
The hosts and paths are examples, and the two parsers are yours to write for the site you collect from. Amounts are stored raw with their currency and a taxes flag; convert currencies at analysis time.
- A timeout on every call; a
403or429ends the sequence instead of retrying - A pause between sequences spreads the run over the day
- JavaScript-heavy search pages: Playwright. Larger runs: Scrapy. More clients: Python guide
import hashlib
import os
import time
from datetime import datetime, timezone
from urllib.parse import quote
import requests
USER = os.environ["NETDASH_USERNAME"]
PASS = quote(os.environ["NETDASH_PASSWORD"], safe="") # encoded: it sits inside a URL
BASE = "https://travel.example" # example host: use a source whose terms allow collection
GATEWAY = {"GB": "scale-eu.netdash.io:2000", "US": "scale-us.netdash.io:2000"}
CURRENCY = {"GB": "GBP", "US": "USD"}
def parse_offer_ids(html):
raise NotImplementedError("site-specific: offer IDs from the results page")
def parse_price(html):
raise NotImplementedError("site-specific: (amount, currency, taxes_included)")
def collect(route, travel_date, market="GB"):
# One sticky session per search sequence, reproducible from its inputs.
sid = hashlib.sha256(f"travel.example:{market}:{route}:{travel_date}".encode()).hexdigest()[:8]
proxy = f"http://{USER}-cc-{market}-session-{sid}-ttl-30:{PASS}@{GATEWAY[market]}"
proxies = {"http": proxy, "https": proxy} # both keys, or HTTPS requests bypass the proxy
with requests.Session() as s: # one cookie jar per sequence
def get(path, **params):
# Proxies on every call: session-level proxies can be overridden by environment variables.
# A wrong username or password raises requests.exceptions.ProxyError (407).
r = s.get(f"{BASE}{path}", params=params, proxies=proxies, timeout=30)
r.raise_for_status() # a 403 or 429 ends the sequence; no retries
return r
get("/", market=market, currency=CURRENCY[market]) # set the public market selector once
results = get("/flights/search", route=route, date=travel_date)
offer_id = parse_offer_ids(results.text)[0]
amount, currency, taxes_included = parse_price(get(f"/flights/offers/{offer_id}").text)
return {
"route": route,
"travel_date": travel_date,
"point_of_sale": market,
"amount": amount, # raw, as listed
"currency": currency,
"taxes_included": taxes_included,
"session": sid,
"fetched_at": datetime.now(timezone.utc).isoformat(),
}
if __name__ == "__main__":
for route, travel_date in [("LHR-JFK", "2026-12-14"), ("LGW-BCN", "2026-12-14")]:
print(collect(route, travel_date))
time.sleep(120) # spread sequences over the dayStore prices so markets stay comparable
A fare in pounds with taxes included and a fare in dollars without them can’t be compared directly. Store what the site showed, with enough context to normalize it later, and convert currencies at analysis time with a dated exchange rate.
- Raw amount and currency, as listed
- A taxes-and-fees-included flag
- Route or property, travel dates and search parameters
fetched_atin UTC and the exit country (point of sale)- The session ID, so each sequence can be traced
Rate parity for your own property
Hotels and their revenue teams can use the same setup to check that their own rates display correctly on the public channels that sell them, market by market: the right rate, currency and taxes for each point of sale.
Check listings of properties you own or manage, and raise mismatches with the channel through your agreement with it.
Which product to collect fares with
Residential proxies
Self-servePoint-of-sale pages per country, sticky per search sequence. The examples use the Scale plan.
From $1.20/GB, graduated per order
Mobile proxies
Self-serveFares and rates as shown on the mobile web, from mobile exit IPs. Carrier, city and network generation can’t be selected.
From $3.50/GB, graduated per order
Public prices, read-only
Collect publicly listed prices only. Read each site’s terms and robots.txt, and use an official API or affiliate feed where one fits. Keep the request rate modest and spread searches over time. Keep collection read-only, with no bookings or account actions, and stop if a site challenges your requests: netdash doesn’t solve challenges. See how we expect netdash to be used.
Travel data questions
Point of sale, currency, taxes and fees display, and market-specific offers can all depend on the visitor’s country. Collect from the market you analyze. Another exit country shows that market’s published prices; it isn’t a way to get a lower price.
Residential proxies with country targeting and sticky sessions: the exit country sets the point of sale, and a sticky session keeps a search, its results and the detail pages on one exit IP. Collect public pages only, within each site’s terms, and use an official API or affiliate feed where one covers your needs.
A search, its results and the detail pages often depend on state set at search time. One exit IP and one cookie jar keep the sequence consistent.
No. The exit country sets the point of sale; the route or city is a search parameter on the site. Gateways are listed on the locations page.
Where a site offers an official API, affiliate feed or data partnership that covers your needs, use it. Collect public pages only where no such option fits, and within the site’s terms.
Searches × pages per search × average page size gives the GB you need; price it in the calculator. Residential GB are one-time purchases with graduated pricing per order, purchased GB never expire, and you pay for the traffic you use: 1 GB of traffic is 1 GB from your balance.
Collect your first market
Run one search sequence for one point of sale, check the stored record, then extend the matrix to more routes and markets.