Tasks
Synchronous single-target scraping
/task List your tasks
Your tasks newest first, including the tasks inside jobs and crawls. Each item carries the
target url (unlocker and map tasks) but never the result: fetch that with GET /task/{task_id}.
Pass next_cursor back as cursor for the next page; it is absent on the last page.
Unknown status or type values match nothing.
statusstringtypestringjob_idstring400 INVALID_QUERY_PARAM.start_datestring400 INVALID_DATE_FORMAT.end_datestringstart_date answers 400 INVALID_DATE_RANGE.limitinteger400 INVALID_QUERY_PARAM. Default: 50.cursorstringnext_cursor of the previous page. A cursor that does not decode answers 400 INVALID_CURSOR.curl https://scraping-api.datafuel.ai/api/v1/task \ --header 'X-API-Key: df_key_your_key_here'
{ "tasks": [ { "id": "7b0e8c1a-3f4d-4e59-9a61-2c8d5e7f9b10", "job_id": "1d2c3b4a-5e6f-4a7b-8c9d-0e1f2a3b4c5d", "type": "unlocker", "status": "completed", "url": "https://example.com/product/1", "credit_cost": 1, "created_at": "2026-09-29T10:00:00Z", "processed_at": "2026-09-29T10:00:02Z" }, { "id": "9c1f2e3d-4b5a-4c6d-8e7f-a0b1c2d3e4f5", "job_id": null, "type": "llm_scraping", "status": "failed", "credit_cost": 100, "created_at": "2026-09-29T09:58:11Z", "failed_at": "2026-09-29T09:58:40Z" } ], "next_cursor": "MTc1OTEzOTQ5MTAwMDAwMDAwMHw5YzFmMmUzZC00YjVhLTRjNmQtOGU3Zi1hMGIxYzJkM2U0ZjU" }
{ "code": "INVALID_QUERY_PARAM", "message": "limit, page and job_id must be valid values" }
{ "code": "UNAUTHORIZED", "message": "You are not authorized to perform this action" }
/task type: unlocker · synchronousUnlocker
Executes one scrape and waits for completion. The connection stays open until the
result is ready, so set your HTTP client timeout generously (120s+ recommended
for js_rendering or llm_scraping workloads).
Every response carries a metadata envelope (status_code, final_url,
redirected, credits_used, blocked, ...) next to result; see
ResultMeta. Bodies above 50 MB are cut off (request engine) or fail
(browser engine). A blocked target (403/429/503, anti-bot wall) fails the
task and refunds it; blocked, protection and status_code tell you why.
Accepted type values: unlocker, llm_scraping, serp, map. crawl is
rejected here with 400 UNSUPPORTED_TASK_TYPE; use POST /crawl.
If the task outlives the request (10 minutes) the answer is 202 TASK_STILL_PROCESSING with the task id: poll GET /task/{id}, or resend with
the same Idempotency-Key.
Idempotency-Keystringtype, proxy fields or attributes) is rejected with 422.typeREQUIREDstringPOST /task accepts unlocker, llm_scraping, serp and map (crawl answers 400 UNSUPPORTED_TASK_TYPE, use POST /crawl); POST /job accepts unlocker, llm_scraping and serp.proxy_typestringllm_scraping and serp.proxy_countrystringattributes.proxy_country is not set. Ignored for serp.proxy_citystringproxy_statestringproxy_asnstringproxy_session_idDEPRECATEDstringattributes.proxy_session_id instead.proxy_ttlDEPRECATEDintegerattributes.proxy_ttl instead.urlREQUIREDstringmethodstring400 INVALID_ATTRIBUTES. Default: "GET".bodystringmethod POST, PUT or PATCH, on both
engines (js_rendering on or off).content_typestringbody. A Content-Type in headers takes precedence.headersobjectheader_orderarray<string>cookie_stringstringuser_agent_typestringuser_agentstringuser_agent_typejs_renderingbooleanredirected / final_url in the
response either way.
Default: false.js_instructionsarray<object> | objectjs_rendering only). Recommended form: an array of
single-action objects, run in order, where an action may repeat, e.g.
[{"fill": ["input[name=q]", "laptops"]}, {"click": "button[type=submit]"}, {"wait_ms": 1000}].
The older object form keyed by action ({"fill": [...], "click": "..."}) is still accepted,
but its order is not guaranteed and an action cannot repeat. The supported actions and their
argument shapes are listed by GET /config/js-instructions; actions marked iframe also
accept the iframe_ prefix. Anything else (a string, a number, an array element that is not
a single-action object, an unknown action) answers 400 INVALID_ATTRIBUTES.block_resourcestring | array<string>400 INVALID_ATTRIBUTES.wait_for_selectorstringjs_rendering only: CSS selector to wait for before capturingwait_for_selector_timeout_msintegerjs_rendering only: timeout of wait_for_selector Default: 3000.extract_selectorstringselector) or a JSON-encoded object of
name → selector for several fields. A JSON object (not a string) answers
400 INVALID_ATTRIBUTES. Append @attr to read an attribute instead of the text.
The result is {"data": {name: [values...]}} and result_format is forced to json.extract_regexstringregex) or a JSON-encoded object of name → pattern. The first capture group is returned when
present, otherwise the whole match; all matches are collected as a list.result_formatstringhtml: raw page. markdown: cleaned text with a title/meta header,
best for LLMs. json: schema.org / JSON-LD and embedded JSON objects.
png / jpeg: full-page screenshot, base64; needs js_rendering: true
(the request engine returns html instead).
Default: "html".result_templatestringinclude_imagesbooleanfalse drops  images (and the links that
only wrapped them); signed image URLs often dominate the token
count of a listing page. The MCP server defaults this to false.
Default: true.main_content_onlyboolean<main> / <article> container when the page has one. Default: false.result_use_aibooleanresult_ai_formatobjectresult_ai_promptstringai_providerstringai_modelstringai_api_keystringproxy_session_idstringproxy_ttlintegerproxy_typestringproxy_type. Set the plan at the top level; that is the one that is billed.proxy_countrystringproxy_countryproxy_citystringproxy_cityproxy_statestringproxy_stateproxy_asnstringproxy_asncurl https://scraping-api.datafuel.ai/api/v1/task \ --request POST \ --header 'Content-Type: application/json' \ --header 'X-API-Key: df_key_your_key_here' \ --data '{ "type": "unlocker", "proxy_type": "Premium", "proxy_country": "US", "attributes": { "url": "https://example.com/product/123", "method": "GET", "js_rendering": true, "wait_for_selector": "#price", "result_format": "json" } }'
{ "id": "123e4567-e89b-12d3-a456-426614174000", "status": "completed", "status_code": 200, "final_url": "https://example.com/product/123", "redirected": false, "credits_used": 10, "duration_ms": 5432, "blocked": false, "result": { "data": "# Product 123\n\nPrice: $19.99\n\nIn stock, ships in 2 days." } }
{ "id": "123e4567-e89b-12d3-a456-426614174000", "code": "TASK_STILL_PROCESSING", "message": "The task is still being processed. Please try again." }
{ "code": "INVALID_ATTRIBUTES", "message": "Invalid attributes for selected task type" }
{ "code": "UNAUTHORIZED", "message": "You are not authorized to perform this action" }
{ "code": "INSUFFICIENT_CREDITS", "message": "You do not have enough credits to perform this action" }
{ "code": "FORBIDDEN", "message": "You do not have permission to perform this action" }
{ "code": "TASK_ALREADY_EXISTS", "message": "A task with this id already exists; retry the request" }
{ "code": "IDEMPOTENCY_KEY_REUSED", "message": "Idempotency-Key was already used for a different request" }
{ "code": "CONCURRENCY_LIMIT_REACHED", "message": "You have reached your concurrency limit" }
{ "code": "ENGINE_UNAVAILABLE", "message": "This engine is switched off at the moment: temporarily unavailable" }
/task type: llm_scraping · synchronousLLM scraping
Executes one scrape and waits for completion. The connection stays open until the
result is ready, so set your HTTP client timeout generously (120s+ recommended
for js_rendering or llm_scraping workloads).
Every response carries a metadata envelope (status_code, final_url,
redirected, credits_used, blocked, ...) next to result; see
ResultMeta. Bodies above 50 MB are cut off (request engine) or fail
(browser engine). A blocked target (403/429/503, anti-bot wall) fails the
task and refunds it; blocked, protection and status_code tell you why.
Accepted type values: unlocker, llm_scraping, serp, map. crawl is
rejected here with 400 UNSUPPORTED_TASK_TYPE; use POST /crawl.
If the task outlives the request (10 minutes) the answer is 202 TASK_STILL_PROCESSING with the task id: poll GET /task/{id}, or resend with
the same Idempotency-Key.
Idempotency-Keystringtype, proxy fields or attributes) is rejected with 422.typeREQUIREDstringPOST /task accepts unlocker, llm_scraping, serp and map (crawl answers 400 UNSUPPORTED_TASK_TYPE, use POST /crawl); POST /job accepts unlocker, llm_scraping and serp.proxy_typestringllm_scraping and serp.proxy_countrystringattributes.proxy_country is not set. Ignored for serp.proxy_citystringproxy_statestringproxy_asnstringproxy_session_idDEPRECATEDstringattributes.proxy_session_id instead.proxy_ttlDEPRECATEDintegerattributes.proxy_ttl instead.promptREQUIREDstringengineREQUIREDstringGET /config/capabilities.websearchbooleanfollow_up_promptstringproxy_countrystringproxy_countrylocationstringresult_formatstringjson.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' \ --data '{ "type": "llm_scraping", "attributes": { "prompt": "best CRM tools for startups 2026", "engine": "perplexity", "websearch": true } }'
{ "id": "123e4567-e89b-12d3-a456-426614174000", "status": "completed", "credits_used": 100, "duration_ms": 18210, "result": { "data": { "answer": "For most startups HubSpot's free CRM is the easiest start; Pipedrive suits sales-led teams…", "sources": [ { "title": "The 10 best CRM tools for startups", "url": "https://example.com/best-crm" } ] } } }
{ "id": "123e4567-e89b-12d3-a456-426614174000", "code": "TASK_STILL_PROCESSING", "message": "The task is still being processed. Please try again." }
{ "code": "INVALID_ATTRIBUTES", "message": "Invalid attributes for selected task type" }
{ "code": "UNAUTHORIZED", "message": "You are not authorized to perform this action" }
{ "code": "INSUFFICIENT_CREDITS", "message": "You do not have enough credits to perform this action" }
{ "code": "FORBIDDEN", "message": "You do not have permission to perform this action" }
{ "code": "TASK_ALREADY_EXISTS", "message": "A task with this id already exists; retry the request" }
{ "code": "IDEMPOTENCY_KEY_REUSED", "message": "Idempotency-Key was already used for a different request" }
{ "code": "CONCURRENCY_LIMIT_REACHED", "message": "You have reached your concurrency limit" }
{ "code": "ENGINE_UNAVAILABLE", "message": "This engine is switched off at the moment: temporarily unavailable" }
/task type: serp · synchronousSERP
Executes one scrape and waits for completion. The connection stays open until the
result is ready, so set your HTTP client timeout generously (120s+ recommended
for js_rendering or llm_scraping workloads).
Every response carries a metadata envelope (status_code, final_url,
redirected, credits_used, blocked, ...) next to result; see
ResultMeta. Bodies above 50 MB are cut off (request engine) or fail
(browser engine). A blocked target (403/429/503, anti-bot wall) fails the
task and refunds it; blocked, protection and status_code tell you why.
Accepted type values: unlocker, llm_scraping, serp, map. crawl is
rejected here with 400 UNSUPPORTED_TASK_TYPE; use POST /crawl.
If the task outlives the request (10 minutes) the answer is 202 TASK_STILL_PROCESSING with the task id: poll GET /task/{id}, or resend with
the same Idempotency-Key.
Idempotency-Keystringtype, proxy fields or attributes) is rejected with 422.typeREQUIREDstringPOST /task accepts unlocker, llm_scraping, serp and map (crawl answers 400 UNSUPPORTED_TASK_TYPE, use POST /crawl); POST /job accepts unlocker, llm_scraping and serp.proxy_typestringllm_scraping and serp.proxy_countrystringattributes.proxy_country is not set. Ignored for serp.proxy_citystringproxy_statestringproxy_asnstringproxy_session_idDEPRECATEDstringattributes.proxy_session_id instead.proxy_ttlDEPRECATEDintegerattributes.proxy_ttl instead.queryREQUIREDstringq). Accepts Google operators (site:, intitle:, ...).countrystringgl), e.g. us, gb, fr.languagestringhl), e.g. en, en-gb, es-419.pageinteger(page-1) * 10 (start). Default: 1.google_domainstringgoogle.co.uk (a leading www. is dropped). Default google.com; pooled per domain.locationstringuule. Exclusive with
uule and lat/lon. Google may still place the local pack by the exit IP.uulestringlocation, lat/lon.latnumberlon.lonnumberlat.radiusintegerlocation, uule or lat/lon.crstring|-delimited upper-case codes, e.g. countryFR|countryDE.lrstring|-delimited, e.g. lang_fr|lang_de.tbsstringsafestringactive filters explicit content, off disables.nfprbooleantrue excludes auto-corrected-query results (served via Google's own link).filterbooleantrue on (default); sends 0 only when explicitly false.udsstringkgmidstringsistringludocidstringlsigstringibpstringgwp;0,7.proxy_countrystringcountry and language to target results.result_formatstringjson structured results, markdown LLM-optimized, html raw served page. Default: "json".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' \ --data '{ "type": "serp", "proxy_country": "US", "attributes": { "query": "best CRM tools for startups 2026", "country": "us", "language": "en", "page": 1, "result_format": "json" } }'
{ "id": "123e4567-e89b-12d3-a456-426614174000", "status": "completed", "credits_used": 50, "result": { "data": { "query": "best crm for startups", "url": "https://www.google.com/search?q=best+crm+for+startups&hl=en&gl=us", "page": 1, "organic": [ { "position": 1, "title": "The 10 best CRM tools for startups", "url": "https://example.com/best-crm", "displayed_link": "example.com › best-crm", "snippet": "We tested 25 CRMs…" } ], "questions": [ { "text": "Which CRM is best for a startup?" } ], "related_searches": [ { "query": "free crm for startups" } ] } } }
{ "id": "123e4567-e89b-12d3-a456-426614174000", "code": "TASK_STILL_PROCESSING", "message": "The task is still being processed. Please try again." }
{ "code": "INVALID_ATTRIBUTES", "message": "Invalid attributes for selected task type" }
{ "code": "UNAUTHORIZED", "message": "You are not authorized to perform this action" }
{ "code": "INSUFFICIENT_CREDITS", "message": "You do not have enough credits to perform this action" }
{ "code": "FORBIDDEN", "message": "You do not have permission to perform this action" }
{ "code": "TASK_ALREADY_EXISTS", "message": "A task with this id already exists; retry the request" }
{ "code": "IDEMPOTENCY_KEY_REUSED", "message": "Idempotency-Key was already used for a different request" }
{ "code": "CONCURRENCY_LIMIT_REACHED", "message": "You have reached your concurrency limit" }
{ "code": "ENGINE_UNAVAILABLE", "message": "This engine is switched off at the moment: temporarily unavailable" }
/task type: map · synchronousMap
Executes one scrape and waits for completion. The connection stays open until the
result is ready, so set your HTTP client timeout generously (120s+ recommended
for js_rendering or llm_scraping workloads).
Every response carries a metadata envelope (status_code, final_url,
redirected, credits_used, blocked, ...) next to result; see
ResultMeta. Bodies above 50 MB are cut off (request engine) or fail
(browser engine). A blocked target (403/429/503, anti-bot wall) fails the
task and refunds it; blocked, protection and status_code tell you why.
Accepted type values: unlocker, llm_scraping, serp, map. crawl is
rejected here with 400 UNSUPPORTED_TASK_TYPE; use POST /crawl.
If the task outlives the request (10 minutes) the answer is 202 TASK_STILL_PROCESSING with the task id: poll GET /task/{id}, or resend with
the same Idempotency-Key.
Idempotency-Keystringtype, proxy fields or attributes) is rejected with 422.typeREQUIREDstringPOST /task accepts unlocker, llm_scraping, serp and map (crawl answers 400 UNSUPPORTED_TASK_TYPE, use POST /crawl); POST /job accepts unlocker, llm_scraping and serp.proxy_typestringllm_scraping and serp.proxy_countrystringattributes.proxy_country is not set. Ignored for serp.proxy_citystringproxy_statestringproxy_asnstringproxy_session_idDEPRECATEDstringattributes.proxy_session_id instead.proxy_ttlDEPRECATEDintegerattributes.proxy_ttl instead.urlREQUIREDstringsearchstringsitemapstringurl. Take it from the
sitemaps list of a previous result.limitintegerinclude_subdomainsbooleanfalse.ignore_sitemapbooleanfalse.sitemap_onlybooleanignore_sitemap. Default: false.user_agent_typestringuser_agentstringproxy_session_idstringproxy_ttlintegerproxy_countrystringproxy_countryproxy_citystringproxy_statestringproxy_asnstringcurl https://scraping-api.datafuel.ai/api/v1/task \ --request POST \ --header 'Content-Type: application/json' \ --header 'X-API-Key: df_key_your_key_here' \ --data '{ "type": "map", "attributes": { "url": "https://example.com", "search": "blog", "limit": 200 } }'
{ "id": "123e4567-e89b-12d3-a456-426614174000", "status": "completed", "credits_used": 1, "result": { "data": { "url": "https://example.com/", "links": [ { "url": "https://example.com/blog/", "source": "sitemap", "lastmod": "2026-08-01" } ], "total": 1, "truncated": false, "sitemaps": [ "https://example.com/sitemap.xml" ], "credits": 1, "page_status_code": 200 } } }
{ "id": "123e4567-e89b-12d3-a456-426614174000", "code": "TASK_STILL_PROCESSING", "message": "The task is still being processed. Please try again." }
{ "code": "INVALID_ATTRIBUTES", "message": "Invalid attributes for selected task type" }
{ "code": "UNAUTHORIZED", "message": "You are not authorized to perform this action" }
{ "code": "INSUFFICIENT_CREDITS", "message": "You do not have enough credits to perform this action" }
{ "code": "FORBIDDEN", "message": "You do not have permission to perform this action" }
{ "code": "TASK_ALREADY_EXISTS", "message": "A task with this id already exists; retry the request" }
{ "code": "IDEMPOTENCY_KEY_REUSED", "message": "Idempotency-Key was already used for a different request" }
{ "code": "CONCURRENCY_LIMIT_REACHED", "message": "You have reached your concurrency limit" }
{ "code": "ENGINE_UNAVAILABLE", "message": "This engine is switched off at the moment: temporarily unavailable" }
/task/{task_id} Get a task result
Same body as POST /task. While the task is pending or processing the answer is
202 TASK_STILL_PROCESSING (body {id, code, message}); poll again.
task_idREQUIREDstringcurl https://scraping-api.datafuel.ai/api/v1/task/{task_id} \ --header 'X-API-Key: df_key_your_key_here'
{ "id": "123e4567-e89b-12d3-a456-426614174000", "status": "completed", "status_code": 200, "final_url": "https://example.com/product/123", "redirected": false, "credits_used": 10, "duration_ms": 5432, "blocked": false, "result": { "data": "# Product 123\n\nPrice: $19.99\n\nIn stock, ships in 2 days." } }
{ "id": "123e4567-e89b-12d3-a456-426614174000", "code": "TASK_STILL_PROCESSING", "message": "The task is still being processed. Please try again." }
{ "code": "INVALID_ATTRIBUTES", "message": "Invalid attributes for selected task type" }
{ "code": "UNAUTHORIZED", "message": "You are not authorized to perform this action" }
{ "code": "JOB_NOT_FOUND", "message": "Job not found" }