Scrape a single page

Fetch one URL with POST /task, choose the output format, extract only what you need, and know when to switch on the browser.

Written By Carmine Cella

Last updated About 3 hours ago

POST /task with type: unlocker fetches one page and returns it in the response. It is the right call for one URL at a time, and the building block behind jobs and crawls.

Minimal request

curl https://scraping-api.datafuel.ai/api/v1/task \  --request POST \  --header "Content-Type: application/json" \  --header "X-API-Key: df_key_your_key_here" \  --header "Idempotency-Key: product-123-2026-09-18" \  --data '{    "type": "unlocker",    "proxy_type": "Basic",    "attributes": {      "url": "https://example.com/product/123",      "result_format": "markdown"    }  }'

The call blocks until the page is fetched. Set your client timeout to at least 120 seconds; browser and AI workloads can take longer.

Choose the output

result_format controls what result.data contains:

Valueresult.data is
markdownClean Markdown of the page. Best for LLM input and search indexes.
htmlThe raw HTML.
jsonSchema.org / JSON-LD data and embedded JSON objects found on the page, as an object.
png, jpegA screenshot, base64-encoded. Needs js_rendering: true.

Two flags shrink Markdown output a lot: main_content_only: true drops navigation, footers and sidebars, and include_images: false drops image references.

Extract only what you need

extract_selector maps names to CSS selectors and returns an object instead of the whole page:

"attributes": {  "url": "https://example.com/product/123",  "extract_selector": {    "title": "h1",    "price": ".price",    "links": "a @href"  }}

Append @attr to a selector to read an attribute instead of the text. extract_regex does the same with regular expressions. Both return result.data as an object.

When to switch on the browser

js_rendering: true renders the page in a real browser before extracting. It costs five times more on Basic and twice more on Premium, so use it only when the request engine falls short:

  • The result is empty or contains only a loading shell.
  • redirected is true and you wanted the filtered URL you asked for, not the canonical page.
  • The content appears only after client-side rendering.

With the browser on, wait_for_selector holds the capture until an element exists, and js_instructions can click, scroll or type before the capture.

Read the response

result.data is a string for markdown and html, an object for json, extract_selector and AI output. Always check the fields next to it: a status_code of 404 still completes and bills, and blocked: true means the page was refused and the task refunded. Read the result envelope walks through every field.

Same request, later

Every task gets an id. GET /task/{task_id} returns the same result again, so you never have to pay twice for a page you already fetched.