Shops, listings, job boards, tables, search results, pages behind a login. If it has a URL, Xuivi can scrape it. Describe what you want, or drop in a scraper definition. JavaScript, proxies, bot walls, pagination and retries are handled for you. Pay only for pages that succeed. Credits never expire.
No card. No subscription. EU-hosted on Azure West Europe.
xuivi — price scraperGET /scrape/byUrl
# one call, any shop, no definition neededcurl"https://api.xuivi.com/scrape/byUrl?url=https://www.etos.nl/producten/oral-b-precision-clean-opzetborstels-wit-4-stuks-120513281.html" \
-H"x-api-key: $XUIVI_KEY"▍
The parts of scraping you would rather not build: engines, proxies, retries, pagination, sessions and the parsing that turns messy HTML into fields you can trust. Product pages get a shortcut; everything else gets a definition.
Scraper definitions, not scraper code
A scraper is JSON: steps with an input scheme, an output scheme and a target URL. Chain them, so a search feeds a detail page. Listings, job boards, spec tables, dashboards: add a website by adding rows, not by shipping a release.
Zero-config price scraper
Point it at any product URL. It reads LD+JSON, microdata, OpenGraph and the GA4 dataLayer, then hands back title, brand, price, currency, image and canonical URL.
AI
Build it with AI
Type what you want to see. Xuivi drafts the definition, runs it against the page, and corrects its own selectors until the output validates.
AI
Self-healing definitions
When a site changes its markup, the definition notices its own output drifting, re-derives the selectors and keeps your feed alive without a ticket.
Beats bot detection
Stealth Chromium, rotating residential proxies by country, cookie and session reuse, and per-domain backoff that honours Retry-After instead of hammering.
Real browsers when it matters
Plain HTTP by default. Switch a single step to Playwright or Puppeteer, wait for a selector, click, type, fill forms, step into iframes.
Lists and pagination
A list selector turns one page into many records. A next-page selector keeps walking until the site runs out of results.
Logged-in scraping
Record an authentication flow once. Xuivi replays it, caches the session for as long as you allow, and refreshes it when it expires.
Jobs that finish
Post thousands of inputs. Xuivi batches them, runs them in parallel, retries until your required success rate is met, then calls your webhook with the results.
Live demo
Watch a page become data.
Three ways in: paste a product URL, hand over a definition, or just describe what you want. Shops, housing listings, job boards: the pipeline you see is the one that runs in production. Recorded runs, real shapes.
GET
Try:
Pipeline
HttpClient
Resolve
etos.nl → known shop, ld+json profile
Engine
HttpClient chosen (server-rendered)
Fetch
200 OK · 214 KB · 318 ms
Render
Not needed
Extract
schema.org Product found in ld+json
Validate
price ✓ currency ✓ title ✓ image ✓
console
waiting…
Output
JSON
Press Scrape to run this example.
How it works
Three calls from URL to dataset.
01
Describe or define
Prompt the AI with what you want, paste a product URL for the zero-config price scraper, or write a definition by hand. Each one lives in your workspace and is versioned.
Poll the status endpoint or wait for the webhook. Every line carries its input, its result and, when a page failed, the reason. Failed lines cost nothing.
The right browser for every step. Never more than you need.
A definition picks one engine, and any single step can overrule it. Search on plain HTTP, render only the detail page, go stealth only for the one site that fights back. Credits follow the engine, so cheap steps stay cheap.
Set proxyCountryCode once per definition. Exits rotate per request; sessions can be pinned.
API
Plain HTTP. Any language. Results pushed to you.
One API key. Three endpoints for single pages, definitions and jobs. Every job reports total, succeeded, failed and success rate while it runs, and posts the full result set to your callback when it finishes.
GET/scrape/byUrl· zero-config product extraction
POST/scrape/byDefinition· run a definition for one input
POST/jobs/start· thousands of inputs, batched and retried
# start a job with three inputs, get results on your webhookcurl -X POST "https://api.xuivi.com/jobs/start?scraper=etos-product&callbackUrl=https://you.example/hook" \
-H "x-api-key: $XUIVI_KEY" \
-H "content-type: application/json" \
-d '[{"ean":"4210201192237"},{"ean":"8001090304841"},{"ean":"3014260002879"}]'# → 202 Accepted{ "jobId": "6278aaf5-b503-4b58-a085-a45d8de04e54", "success": true }# poll instead of waiting for the callbackcurl"https://api.xuivi.com/jobs/6278aaf5-b503-4b58-a085-a45d8de04e54/status" -H "x-api-key: $XUIVI_KEY"{ "isCompleted": true, "totalItems": 3, "itemsSucceeded": 3, "itemsFailed": 0, "successRate": 100 }
using System.Net.Http.Json;
var http = newHttpClient { BaseAddress = new("https://api.xuivi.com") };
http.DefaultRequestHeaders.Add("x-api-key", Environment.GetEnvironmentVariable("XUIVI_KEY"));
var inputs = new[] { new { ean = "4210201192237" }, new { ean = "8001090304841" } };
var started = await http.PostAsJsonAsync(
"/jobs/start?scraper=etos-product&callbackUrl=https://you.example/hook", inputs);
var job = await started.Content.ReadFromJsonAsync<StartResponse>();
Console.WriteLine($"job {job!.JobId} accepted");
// later, or from your webhook handler:var results = await http.GetFromJsonAsync<ScrapeJob>($"/jobs/{job.JobId}");
foreach (var line in results!.ScrapeResults)
Console.WriteLine($"{line.Input["ean"]} → {line.Status}: {line.Result?["price"]}");
recordStartResponse(Guid JobId, bool Success);
import os, requests
API = "https://api.xuivi.com"
headers = {"x-api-key": os.environ["XUIVI_KEY"]}
# zero-config price scraper: one URL in, one product out
r = requests.get(f"{API}/scrape/byUrl", headers=headers, params={
"url": "https://www.coolblue.nl/product/942567/sonos-era-100-zwart.html",
"useBrowser": True, # render JavaScript"proxyCountry": "NL", # residential exit
})
product = r.json()
print(product["productTitle"], product["price"], product["currency"])
# or a whole catalog as a job
job = requests.post(f"{API}/jobs/start", headers=headers,
params={"scraper": "etos-product"},
json=[{"ean": e} for e in open("eans.txt").read().split()]).json()
print("job", job["jobId"])
const API = "https://api.xuivi.com";
const headers = { "x-api-key": process.env.XUIVI_KEY, "content-type": "application/json" };
// run a definition for one input, synchronouslyconst res = await fetch(`${API}/scrape/byDefinition?scraper=bol-offers`, {
method: "POST",
headers,
body: JSON.stringify({ ean: "9200000007373193" }),
});
const { result } = await res.json();
// result is an array because the step has a listSelectorfor (const offer of result) console.log(offer.seller, offer.price, offer.delivery);
Pricing
Buy credits. Use them whenever.
No subscription, no monthly reset, no charge for a page that did not come back. Start with 1,000 credits on us.
Credits never expire and carry over between packs. Failed pages are free. Enterprise volume, SLA and dedicated proxies: hello@xuivi.com
What would it cost me?
estimate
20,000
1k10k100k1M2M
Credits needed
60,000
Buy
Growth
Per month
€49.00
≈ €2.45 per 1,000 pages
Leftover credits stay in your account, so a quiet month is not a wasted month.
How credits are counted
Per successful page. A page that fails, times out or is blocked costs nothing.
Plain fetch
HttpClient engine, datacenter IP
1
JavaScript render
Playwright or Puppeteer, full DOM
5
Residential proxy
Added on top of the engine cost, any country
+10
Stealth mode
Stealth browser plus residential proxy, all-in
25
Price scraper
Zero-config product extraction, engine picked for you
3
FAQ
Questions people ask before they buy.
What is a credit?
One credit is one successful plain-HTTP page. A JavaScript render is 5, a residential proxy adds 10, stealth mode is 25 all-in, and the zero-config price scraper is a flat 3 whatever it had to do. Pages that fail cost nothing.
Do credits expire?
No. Credits stay in your account until you use them and stack across packs. There is no monthly reset.
What is a scraper definition?
A JSON document that describes a scrape as steps. Each step has an input scheme, a target URL with placeholders, and an output scheme written in a small instruction language (xpath::, fallback::, combination::, table::, literal:: and friends). Steps chain: the output of one becomes the input of the next. You can write them by hand, generate them from a prompt, or start from the price scraper.
Which websites work?
Any public web page: shops, marketplaces, real-estate and job listings, directories, spec tables, search results, dashboards behind a login. Product pages get a shortcut: the price scraper reads schema.org ld+json, microdata, OpenGraph and the GA4 dataLayer with zero config. Everything else is a definition with XPath selectors, and the AI builder writes it for you.
Can Xuivi scrape behind a login?
Yes. Record an authentication flow once (inputs, clicks, delays). Xuivi replays it, keeps the session cookies for as long as you allow, and refreshes them when they expire.
How do you deal with bot detection?
Layered. Plain HTTP with a proper cookie jar is enough for most shops. Beyond that: real Chromium via Playwright or Puppeteer, a stealth profile that patches browser fingerprints, rotating residential proxies per country, session pinning, and per-domain backoff that honours Retry-After headers so your job slows down instead of getting banned.
What happens when a page fails?
The job retries it with exponential backoff until your required success rate is met or the retry budget is spent. Every result line reports its own status and, on failure, the reason. Failed lines are not charged.
Where does my data live?
Xuivi runs on Azure West Europe. Job inputs and results are stored in EU blob storage under your tenant and are yours to delete.
Is scraping legal?
Scraping publicly available data is common practice for price monitoring, market research and lead generation. You remain responsible for how you use the data and for the terms of the sites you target. Xuivi does not bypass paywalls or scrape personal data on your behalf.
Your first 1,000 pages are on us.
Create a workspace, grab an API key, paste a URL. If it does not come back as clean JSON, you have not spent a thing.