Scrape Duck.ai AI-generated answer 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. 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. You 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. What data can you retrieve with the Duck AI API? The response separates the answer into text blocks and provides the full formatted answer in markdown . Here are the most useful fields to start with: - The full answer: markdown contains the answer in Markdown, including references when present. - Individual answer blocks: text blocks identifies paragraphs, headings, lists, tables, and code blocks through type ; paragraph and heading text is stored in snippet . - Cited sources: references contains source records with a title and link . - Citation connections: A block's reference indexes points to the corresponding source records by their index . - 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. - Conversation context: subsequent request token lets you ask another question with the earlier prompts and answers as context. Sources and suggested searches depend on the answer; citations do not guarantee that an AI-generated answer is correct. See the Duck AI API documentation https://serpapi.com/duck-ai-api for the complete field and parameter reference. How to use the Duck AI API You can use this API with any programming languages or AI tools. Try it in the playground We have a playground where you can play around with any of our APIs and their parameters: Inspect 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. Get your API key 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 . In a macOS or Linux terminal, set the environment variable used by the examples below: export SERPAPI API KEY="YOUR SERPAPI API KEY" Replace the placeholder locally with your own key. Keep it out of source files, shared screenshots, and public logs. Make a GET request Send 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: https://serpapi.com/search?engine=duck ai&q=where%20does%20coffee%20grow%3F&api key=YOUR SERPAPI API KEY For a Markdown response, add output=md to the same request: https://serpapi.com/search?engine=duck ai&q=where%20does%20coffee%20grow%3F&api key=YOUR SERPAPI API KEY&output=md 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. cURL implementation Here is the equivalent GET request using cURL: curl --get "https://serpapi.com/search" \ --data-urlencode "engine=duck ai" \ --data-urlencode "q=where does coffee grow?" \ --data-urlencode "api key=$SERPAPI API KEY" 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. Python implementation Use the official SerpApi Python SDK https://serpapi.com/integrations/python . In your Python virtual environment, install: pip install serpapi Create a file named main.py : python import os import serpapi client = serpapi.Client api key=os.environ "SERPAPI API KEY" , timeout=60, response = client.search { "engine": "duck ai", "q": "where does coffee grow?", } if "error" in response: raise SystemExit "Duck AI returned an error. Check your key and request in the Playground." answer = response.get "markdown" if not answer: raise SystemExit "No answer was returned for this prompt." print answer for reference in response.get "references", :3 : print f"\nSource: {reference 'title' }" print f"URL: {reference 'link' }" Run it in the terminal where you set your API key: python main.py The 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. Some answers have no cited sources, so the references loop may have nothing to print even when an answer is returned. JavaScript implementation Use a current Node.js LTS release and the official SerpApi JavaScript library https://github.com/serpapi/serpapi-javascript/ : npm install serpapi Create a file named main.js : js async function main { const apiKey = process.env.SERPAPI API KEY; if apiKey { console.error "Set SERPAPI API KEY before running main.js." ; process.exitCode = 1; return; } const { getJson } = await import "serpapi" ; const response = await getJson { engine: "duck ai", q: "where does coffee grow?", api key: apiKey, } ; if "error" in response { console.error "Duck AI returned an error. Check your key and request in the Playground." ; process.exitCode = 1; return; } if response.markdown { console.error "No answer was returned for this prompt." ; process.exitCode = 1; return; } console.log response.markdown ; for const reference of response.references ?? .slice 0, 3 { console.log \nSource: ${reference.title} ; console.log URL: ${reference.link} ; } } main .catch = { console.error "The request could not complete. Check your SDK installation, API key, and network connection." ; process.exitCode = 1; } ; Run it in the terminal where you set your API key: node main.js Other languages and no-code options See 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/ . For 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. Customize your Duck AI requests Interesting parameter in this API: - 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. - subsequent request token : Pass the token from the preceding response together with a new q to continue that conversation. For example, ask the same coffee question with Claude Haiku 4.5 curl --get "https://serpapi.com/search" \ --data-urlencode "engine=duck ai" \ --data-urlencode "q=where does coffee grow?" \ --data-urlencode "model=claude-haiku-4-5" \ --data-urlencode "api key=$SERPAPI API KEY" Ask a follow-up question After the first answer, you might ask: "which of those countries produces the most?" This is the follow-up prompt shown in the documentation. Append the following to the earlier Python example. It reuses that example's client and response , keeping the same default model: token = response.get "subsequent request token" if not token: raise SystemExit "No conversation token was returned." follow up = client.search { "engine": "duck ai", "q": "which of those countries produces the most?", "subsequent request token": token, } if "error" in follow up: raise SystemExit "The follow-up request failed." answer = follow up.get "markdown" if not answer: raise SystemExit "No answer was returned for the follow-up prompt." print answer This 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. Warning: 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. Scraping DuckDuckGo search results SerpApi also offers a dedicated API to fetch search results from the DuckDuckGo website. Learn more about it here: Conclusion You 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. For related APIs on other AI-answer engines, check out our AI SEO GEO API solution https://serpapi.com/use-cases/ai-seo-geo-api . Frequently asked questions Which parameters are required? A basic request needs engine=duck ai , your prompt in q , and your SerpApi api key . Model selection and the conversation token are optional. Can I choose a different AI model? Yes. 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. Does every answer include sources? No. Duck AI cites sources when it searches the web to answer. Do not assume that references or related searches is present for every prompt. Can I continue the conversation? Yes. 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. Should I use JSON or Markdown? Use 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.