ForHosting KIT · Web Scraping & Monitoring

Scrape a website

Give it a URL and a map of CSS selectors, and it hands back exactly the fields you asked for as structured JSON — no headless browser to babysit, no HTML soup to parse on your end. This is the workhorse endpoint for teams who already know precisely which div, span or table cell holds the data they need.

● StablePer request + per URL$0.040
Use it from WebAPIEmailApp soonTelegram soon

Run this on our servers with your account. Free tools run in your browser; this one bills your KIT balance per the price above.

Built for people who already know their selectors

If you can open dev tools, right-click an element and copy its selector, this endpoint is for you. It suits price monitors, inventory trackers, real-estate listing pullers, job-board watchers and any recurring job where the target page's layout is known and reasonably stable. You define a selector map once — field name to CSS selector — and every request against that page shape reuses it.

What happens after you submit a request

The call to POST /web/scrape-selector returns a task_id immediately; the actual fetch and extraction run asynchronously against our global edge, including JavaScript-rendered pages when the selector targets content injected client-side. When the task finishes you get the result either pushed to your signed webhook or waiting behind a signed link that stays valid for 24 hours, after which the data is deleted and never touches any training pipeline.

CSS selectors: an old idea that still wins

Selectors have described document structure since CSS1 in 1996, and browsers standardized querySelector matching decades ago — which is exactly why they remain the fastest, cheapest way to pull a known field from a known layout. Unlike vision or language models, a selector either matches or it doesn't: zero ambiguity, zero hallucinated fields, and a result you can unit-test.

What you get back, and what happens when a selector misses

The response mirrors your selector map, field by field, with arrays for repeated elements like list items or table rows and null for a selector that matched nothing on that particular page. Because failed extraction attempts are retried automatically up to three times before returning a clear error, a transient timeout or a slow-loading widget won't silently cost you a charge — you are only billed for a task that actually completes.

Where it sits in a bigger pipeline

Most teams chain this endpoint behind a scheduler: cron-trigger a batch of URLs, let each task land on a webhook, and feed the JSON straight into a database, spreadsheet or alerting rule without a human ever opening the source page. Because pricing is a flat per-request base plus a small per-URL fee, it scales predictably whether you are watching five competitor prices or five thousand SKUs.

Competitor price monitoring

Track the .price and .stock-status selectors on a set of competitor product pages daily and feed the JSON into a pricing dashboard.

Real-estate listing aggregation

Pull address, price, square footage and photo count from a listings site using a single selector map reused across thousands of pages.

Job board watching

Extract title, company and posted-date selectors from a careers page each morning to detect new openings before a public feed exists.

Table-based data collection

Target a table row selector to turn an HTML table of exchange rates or specs into a JSON array your app can index directly.

Is the web scraping API free to try?

There's no free tier — free tiers get abused and slow everyone down. Access runs on a prepaid ForHosting KIT balance: top up from $10.00 (it never expires) and each request is charged at its published price, so a call with no balance returns HTTP 402. No subscription, no tokens, no invented credits, and a failed task is never charged.

How much does web.scrape_selector cost?

$0.040 per request plus $0.001 per URL processed, billed only when the task actually completes.

Does it handle JavaScript-rendered pages?

Yes, the fetch layer renders pages before applying your CSS selectors, so content injected by client-side scripts is matchable just like static HTML.

What happens if my selector doesn't match anything?

That field comes back as null in the response instead of failing the whole task, so one broken selector in a map doesn't block the rest of your data.

Can I scrape multiple URLs with one selector map?

Yes, submit a list of URLs alongside a single selector map when the pages share the same layout, which is the most cost-efficient way to use this endpoint.

How do I get the results back?

Either as a push to your signed webhook when the task finishes, or via a signed link valid for 24 hours if you prefer to poll.

What happens if a scrape fails?

Failed attempts are retried automatically up to three times; if it still fails you get a clear error and are never charged for that task.

How is this different from the AI or schema scraping endpoints?

Selector scraping is the fastest and cheapest option when you already know the exact CSS path to each field; the AI and schema endpoints exist for when layouts vary or you need guaranteed data types.

Everything on this page is available programmatically. This section is for teams who want to wire it into their own systems; everyone else can just use the tool above.

POSThttps://api.kit.forhosting.com/web/scrape-selector

Prefer to automate it? One authenticated POST creates the task; the result comes back by webhook or a signed link. The same capability also runs here on the web, and soon from our app, email and Telegram.

curl -X POST https://api.kit.forhosting.com/web/scrape-selector \
  -H "Authorization: Bearer $KIT_KEY" \
  -H "Content-Type: application/json" \
  -d '{"url":"https://ejemplo.com","selectors":{"titulo":"h1","precio":".price"}}'
{
  "url": "https://ejemplo.com",
  "selectors": {
    "titulo": "h1",
    "precio": ".price"
  }
}
{
  "task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
  "type": "web.scrape_selector",
  "status": "queued",
  "_links": {
    "result": "/tasks/tsk_…/result"
  }
}

The API is asynchronous: the call returns a task_id immediately and the result arrives by webhook. Polling is capped at 1 req/s per task.

Per request$0.040
Per URL$0.001

Published price — no tokens, no invented credits. A failed task is never charged.

timeout_sec30
max_crawl_pages25
HTTPCodeMeaning
401unauthorizedMissing or invalid API key.
402insufficient_balanceYour balance doesn't cover the task price.
404unknown_typeThat task type doesn't exist.
429rate_limitedToo many requests. Use the webhook instead of polling.
422task_failedThe task failed after 3 retries. You are never charged for it.

Read the full KIT documentation →