{"slug": "scrape-duck-ai-ai-generated-answer", "title": "Scrape Duck.ai AI-generated answer", "summary": "SerpApi released a Duck AI API, also called the DuckDuckGo AI Chat API, which returns Duck.ai answers as structured text blocks and Markdown with cited sources when Duck AI uses web search. The API exposes fields including text_blocks, markdown, references with title and link, reference_indexes linking blocks to sources, related_searches, and a subsequent_request_token for follow-up questions, and it is called via a GET request to https://serpapi.com/search with engine=duck_ai, q, and api_key. SerpApi notes that citations do not guarantee an AI-generated answer is correct.", "body_md": "Want to collect an AI-generated answer together with the sources it cites? SerpApi's [Duck AI API](https://serpapi.com/duck-ai-api), also called the DuckDuckGo AI Chat API, returns answers as structured text blocks and Markdown, with cited sources when Duck AI uses web search.\n\nYou can use it to build a small research helper, compare how different models answer a question, or inspect the sources behind an answer. In this tutorial, we'll ask a sample question using cURL, Python, and JavaScript, then choose a model and send a follow-up question.\n\n## What data can you retrieve with the Duck AI API?\n\nThe response separates the answer into `text_blocks` and provides the full formatted answer in `markdown`. Here are the most useful fields to start with:\n\n- **The full answer:**`markdown` contains the answer in Markdown, including references when present.\n- **Individual answer blocks:**`text_blocks` identifies paragraphs, headings, lists, tables, and code blocks through`type` ; paragraph and heading text is stored in`snippet` .\n- **Cited sources:**`references` contains source records with a`title` and`link` .\n- **Citation connections:** A block's`reference_indexes` points to the corresponding source records by their`index` .\n- **Suggested searches:**`related_searches` contains suggested`query` values and a`serpapi_link` for a separate[DuckDuckGo Search API](https://serpapi.com/duckduckgo-search-api) request.\n- **Conversation context:**`subsequent_request_token` lets you ask another question with the earlier prompts and answers as context.\n\nSources and suggested searches depend on the answer; citations do not guarantee that an AI-generated answer is correct.\n\nSee the [Duck AI API documentation](https://serpapi.com/duck-ai-api) for the complete field and parameter reference.\n\n## How to use the Duck AI API\n\nYou can use this API with any programming languages or AI tools.\n\n### Try it in the playground\n\nWe have a playground where you can play around with any of our APIs and their parameters:\n\nInspect the answer blocks, the full Markdown answer, and any returned references. The documentation's example contains paragraphs, a list of growing regions, and cited sources. Your returned wording and sources may differ.\n\n### Get your API key\n\n[Create a SerpApi account](https://serpapi.com/users/sign_up), then copy your key from the [API key page](https://serpapi.com/manage-api-key).\n\nIn a macOS or Linux terminal, set the environment variable used by the examples below:\n\n```\nexport SERPAPI_API_KEY=\"YOUR_SERPAPI_API_KEY\"\n```\n\nReplace the placeholder locally with your own key. Keep it out of source files, shared screenshots, and public logs.\n\n### Make a GET request\n\nSend your prompt to `https://serpapi.com/search` with `engine=duck_ai`, `q`, and `api_key`. JSON is the default, so you do not need an output parameter:\n\n```\nhttps://serpapi.com/search?engine=duck_ai&q=where%20does%20coffee%20grow%3F&api_key=YOUR_SERPAPI_API_KEY\n```\n\nFor a Markdown response, add `output=md` to the same request:\n\n```\nhttps://serpapi.com/search?engine=duck_ai&q=where%20does%20coffee%20grow%3F&api_key=YOUR_SERPAPI_API_KEY&output=md\n```\n\n[Markdown output](https://serpapi.com/markdown-output) is a curated version of the response. Use JSON when you need exact fields, citation indexes, or a conversation token. There is an important distinction here: the JSON response already contains an answer string called `markdown`. Setting `output=md` changes the format of the entire response, rather than adding that field.\n\n### cURL implementation\n\nHere is the equivalent GET request using cURL:\n\n```\ncurl --get \"https://serpapi.com/search\" \\\n  --data-urlencode \"engine=duck_ai\" \\\n  --data-urlencode \"q=where does coffee grow?\" \\\n  --data-urlencode \"api_key=$SERPAPI_API_KEY\"\n```\n\n`q` is your prompt, and `engine` selects the Duck AI API. `--data-urlencode` handles spaces and the question mark for you. Check for an `error` field before using the returned answer.\n\n### Python implementation\n\nUse the [official SerpApi Python SDK](https://serpapi.com/integrations/python). In your Python virtual environment, install:\n\n```\npip install serpapi\n```\n\nCreate a file named `main.py`:\n\n``` python\nimport os\n\nimport serpapi\n\nclient = serpapi.Client(\n    api_key=os.environ[\"SERPAPI_API_KEY\"],\n    timeout=60,\n)\nresponse = client.search({\n    \"engine\": \"duck_ai\",\n    \"q\": \"where does coffee grow?\",\n})\n\nif \"error\" in response:\n    raise SystemExit(\"Duck AI returned an error. Check your key and request in the Playground.\")\n\nanswer = response.get(\"markdown\")\nif not answer:\n    raise SystemExit(\"No answer was returned for this prompt.\")\n\nprint(answer)\nfor reference in response.get(\"references\", [])[:3]:\n    print(f\"\\nSource: {reference['title']}\")\n    print(f\"URL: {reference['link']}\")\n```\n\nRun it in the terminal where you set your API key:\n\n```\npython main.py\n```\n\nThe SDK returns a dictionary-like result, so there is no need to call `.json()`. This script prints the full Markdown answer and up to three source titles and URLs. Printing `markdown` preserves the answer's lists, tables, and code formatting without parsing each block separately.\n\nSome answers have no cited sources, so the references loop may have nothing to print even when an answer is returned.\n\n### JavaScript implementation\n\nUse a current Node.js LTS release and the [official SerpApi JavaScript library](https://github.com/serpapi/serpapi-javascript/):\n\n```\nnpm install serpapi\n```\n\nCreate a file named `main.js`:\n\n``` js\nasync function main() {\n  const apiKey = process.env.SERPAPI_API_KEY;\n  if (!apiKey) {\n    console.error(\"Set SERPAPI_API_KEY before running main.js.\");\n    process.exitCode = 1;\n    return;\n  }\n\n  const { getJson } = await import(\"serpapi\");\n  const response = await getJson({\n    engine: \"duck_ai\",\n    q: \"where does coffee grow?\",\n    api_key: apiKey,\n  });\n\n  if (\"error\" in response) {\n    console.error(\"Duck AI returned an error. Check your key and request in the Playground.\");\n    process.exitCode = 1;\n    return;\n  }\n\n  if (!response.markdown) {\n    console.error(\"No answer was returned for this prompt.\");\n    process.exitCode = 1;\n    return;\n  }\n\n  console.log(response.markdown);\n  for (const reference of (response.references ?? []).slice(0, 3)) {\n    console.log(`\\nSource: ${reference.title}`);\n    console.log(`URL: ${reference.link}`);\n  }\n}\n\nmain().catch(() => {\n  console.error(\"The request could not complete. Check your SDK installation, API key, and network connection.\");\n  process.exitCode = 1;\n});\n```\n\nRun it in the terminal where you set your API key:\n\n```\nnode main.js\n```\n\n### Other languages and no-code options\n\nSee the [other programming-language integrations](https://serpapi.com/integrations), [SerpApi's Make.com app](https://serpapi.com/blog/announcing-serpapis-make-app/), and [SerpApi's verified n8n node](https://serpapi.com/blog/boost-your-n8n-workflows-with-serpapis-verified-node/).\n\nFor engines without a native operation, the announcements describe Make's Universal \"Make an API Call\" module and n8n's generic HTTP Request node. Reuse the endpoint and parameters above with the platform's stored SerpApi credentials.\n\n## Customize your Duck AI requests\n\nInteresting parameter in this API:\n\n- **`model`:** Choose the model answering the prompt. For example,` claude-haiku-4-5` selects Claude Haiku 4.5. The documented default is`gpt-5.6-luna` ; check the documentation for the current supported list.\n- **`subsequent_request_token`:** Pass the token from the preceding response together with a new`q` to continue that conversation.\n\nFor example, ask the same coffee question with Claude Haiku 4.5\n\n```\ncurl --get \"https://serpapi.com/search\" \\\n  --data-urlencode \"engine=duck_ai\" \\\n  --data-urlencode \"q=where does coffee grow?\" \\\n  --data-urlencode \"model=claude-haiku-4-5\" \\\n  --data-urlencode \"api_key=$SERPAPI_API_KEY\"\n```\n\n### Ask a follow-up question\n\nAfter the first answer, you might ask: \"which of those countries produces the most?\" This is the follow-up prompt shown in the documentation.\n\nAppend the following to the earlier Python example. It reuses that example's `client` and `response`, keeping the same default model:\n\n```\ntoken = response.get(\"subsequent_request_token\")\nif not token:\n    raise SystemExit(\"No conversation token was returned.\")\n\nfollow_up = client.search({\n    \"engine\": \"duck_ai\",\n    \"q\": \"which of those countries produces the most?\",\n    \"subsequent_request_token\": token,\n})\n\nif \"error\" in follow_up:\n    raise SystemExit(\"The follow-up request failed.\")\n\nanswer = follow_up.get(\"markdown\")\nif not answer:\n    raise SystemExit(\"No answer was returned for the follow-up prompt.\")\n\nprint(answer)\n```\n\nThis makes one additional API request, which can consume a search credit. For another turn, use the new token from `follow_up`, not the original token. Treat tokens as private context: they hold the conversation and should not be shared in logs or screenshots.\n\nWarning: Conversations longer than about 16,000 characters across prompts and answers cannot be continued because the request becomes too long. This token continues a conversation; it is not a result-pagination cursor.\n\n**Scraping DuckDuckGo search results**\n\nSerpApi also offers a dedicated API to fetch search results from the DuckDuckGo website. Learn more about it here:\n\n## Conclusion\n\nYou can now retrieve a Duck AI answer, read its cited sources, choose a model, and ask a follow-up question using SerpApi. Try a question relevant to your project in the [Duck AI Playground](https://serpapi.com/playground?engine=duck_ai), then use JSON for field-level processing or Markdown for readable answer content.\n\nFor related APIs on other AI-answer engines, check out our [AI SEO (GEO) API solution](https://serpapi.com/use-cases/ai-seo-geo-api).\n\n## Frequently asked questions\n\n### Which parameters are required?\n\nA basic request needs `engine=duck_ai`, your prompt in `q`, and your SerpApi `api_key`. Model selection and the conversation token are optional.\n\n### Can I choose a different AI model?\n\nYes. Set `model` to one of the values in the [Duck AI API documentation](https://serpapi.com/duck-ai-api). The documentation lists `claude-haiku-4-5` among the options and `gpt-5.6-luna` as the default.\n\n### Does every answer include sources?\n\nNo. Duck AI cites sources when it searches the web to answer. Do not assume that `references` or `related_searches` is present for every prompt.\n\n### Can I continue the conversation?\n\nYes. Send a new `q` with the preceding response's `subsequent_request_token`. Use the latest returned token for each turn, and keep the documented conversation-length limit in mind.\n\n### Should I use JSON or Markdown?\n\nUse JSON to work with exact fields, source records, and continuation tokens. Use `output=md` when you want the response as readable Markdown. You can also read the answer's `markdown` string from the default JSON response, as the code examples do.", "url": "https://wpnews.pro/news/scrape-duck-ai-ai-generated-answer", "canonical_source": "https://serpapi.com/blog/scrape-duck-ai-ai-generated-answer/", "published_at": "2026-11-12 05:13:01+00:00", "updated_at": "2026-11-12 05:22:59.251043+00:00", "lang": "en", "topics": ["ai-search", "ai-tools", "generative-ai", "developer-tools"], "entities": ["SerpApi", "Duck.ai", "DuckDuckGo", "Duck AI API", "DuckDuckGo Search API"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/scrape-duck-ai-ai-generated-answer", "markdown": "https://wpnews.pro/news/scrape-duck-ai-ai-generated-answer.md", "text": "https://wpnews.pro/news/scrape-duck-ai-ai-generated-answer.txt", "jsonld": "https://wpnews.pro/news/scrape-duck-ai-ai-generated-answer.jsonld"}}