cd /news/ai-search/scrape-duck-ai-ai-generated-answer · home › topics › ai-search › article
[ARTICLE · art-168155] src=serpapi.com ↗ pub= topic=ai-search verified=true sentiment=· neutral

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.

by read7 min views1 publishedNov 12, 2026
Scrape Duck.ai AI-generated answer
Image: Serpapi (auto-discovered)

Want to collect an AI-generated answer together with the sources it cites? SerpApi's 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 throughtype ; paragraph and heading text is stored insnippet .
  • Cited sources:references contains source records with atitle andlink .
  • Citation connections: A block'sreference_indexes points to the corresponding source records by theirindex .
  • Suggested searches:related_searches contains suggestedquery values and aserpapi_link for a separateDuckDuckGo 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 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, then copy your key from the API key page.

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 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. In your Python virtual environment, install:

pip install serpapi

Create a file named main.py:

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:

npm install serpapi

Create a file named main.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, SerpApi's Make.com app, and SerpApi's verified n8n 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 isgpt-5.6-luna ; check the documentation for the current supported list.
  • subsequent_request_token: Pass the token from the preceding response together with a newq 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, 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.

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. 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.

── more in #ai-search 4 stories · sorted by recency
── more on @serpapi 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
→ Live at https://your-agent.zahid.host ✓
Get free account → Pricing
from €0/mo · no card required
LIVE [news/scrape-duck-ai-ai-ge…] indexed:0 read:7min 2026-11-12 · —