> For the complete documentation index, see [llms.txt](https://docs.pullbay.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.pullbay.com/documentation/api-and-references/duckduckgo.md).

# DuckDuckGo

The Pullbay DuckDuckGo API provides programmatic access to web, image, news, and video search results from DuckDuckGo. Integrate DuckDuckGo's search index into your applications, dashboards, and research pipelines without scraping or browser automation.

**Base URL:** `https://dashboard.pullbay.com/api`

## Overview

The DuckDuckGo service lets you:

* Search the web for a term and get back ranked page results
* Search for images matching a term, including full-size and thumbnail URLs
* Search for news articles matching a term, optionally filtered by recency
* Search for videos matching a term, with duration, publisher, and view-count metadata

All four endpoints are read-only `GET` requests against public DuckDuckGo search results — there's no account or API key on DuckDuckGo's side required, just your Pullbay API key.

## Common Use Cases

* **Competitive Research** — Run the same query across web, news, and image results to see how a competitor, brand, or topic is currently represented in search.
* **Content Monitoring** — Poll the news or web endpoints on a schedule to catch new mentions of a brand, product, or keyword as they appear.
* **SEO / SERP Tracking** — Capture web search result rankings and snippets for a set of target terms over time to track visibility trends.
* **Brand Monitoring Across Media Types** — Combine the search, images, news, and videos endpoints to get a fuller picture of how a name or topic surfaces across different content formats.
* **Research and Due Diligence** — Pull web and news results for a company, person, or topic as a starting point for manual research, without manually running searches in a browser.

## Endpoints

| Endpoint                 | Description                         | Pagination |
| ------------------------ | ----------------------------------- | ---------- |
| `GET /duckduckgo/search` | Search the web via DuckDuckGo       | Offset     |
| `GET /duckduckgo/images` | Search images via DuckDuckGo        | Offset     |
| `GET /duckduckgo/news`   | Search news articles via DuckDuckGo | Offset     |
| `GET /duckduckgo/videos` | Search videos via DuckDuckGo        | Offset     |

***

### Search Web

Returns web search results for `term`.

**Request**

```bash
GET /duckduckgo/search
Authorization: Bearer YOUR_API_KEY
```

**Parameters**

| Parameter    | Type   | Required | Default | Description                                                                                            |
| ------------ | ------ | -------- | ------- | ------------------------------------------------------------------------------------------------------ |
| `term`       | string | Yes      | —       | Search term, 1–255 characters                                                                          |
| `region`     | string | Yes      | —       | DuckDuckGo region code. Closed list of 63 values — see [Region Codes](#region-codes)                   |
| `safeSearch` | string | Yes      | —       | One of `false`, `moderate`, `strict` — see [Safe Search Levels](#safe-search-levels)                   |
| `offset`     | number | No       | —       | Result offset, 0 or greater                                                                            |
| `time`       | string | No       | —       | Recency filter. One of `a`, `d`, `w`, `m`, `y` — see [Pagination and Recency](#pagination-and-recency) |

**Example**

```bash
curl -G "https://dashboard.pullbay.com/api/duckduckgo/search" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -d term="OpenAI" \
  -d region=us-en \
  -d safeSearch=moderate \
  -d offset=0
```

**Response**

```json
{
  "status": 200,
  "message": "OK",
  "success": true,
  "data": [
    {
      "title": "OpenAI",
      "description": "We believe our research will eventually lead to artificial general intelligence, a system that can solve human-level problems.",
      "hostname": "openai.com",
      "icon": "https://external-content.duckduckgo.com/ip3/openai.com.ico",
      "url": "https://openai.com/"
    }
  ],
  "pricing": { "creditsCharged": 1 }
}
```

**Response Schema**

| Field                    | Type   | Description                                             |
| ------------------------ | ------ | ------------------------------------------------------- |
| `data`                   | array  | Array of [Search Result objects](#search-result-object) |
| `pricing.creditsCharged` | number | Credits charged for this request                        |

**Credit cost:** dynamic, returned in `pricing.creditsCharged`. No published flat rate.

***

### Search Images

Returns image search results for `term`.

**Request**

```bash
GET /duckduckgo/images
Authorization: Bearer YOUR_API_KEY
```

**Parameters**

| Parameter    | Type   | Required | Default | Description                                                                          |
| ------------ | ------ | -------- | ------- | ------------------------------------------------------------------------------------ |
| `term`       | string | Yes      | —       | Search term, 1–255 characters                                                        |
| `region`     | string | Yes      | —       | DuckDuckGo region code. Closed list of 63 values — see [Region Codes](#region-codes) |
| `safeSearch` | string | Yes      | —       | One of `false`, `moderate`, `strict` — see [Safe Search Levels](#safe-search-levels) |
| `offset`     | number | No       | —       | Result offset, 0 or greater                                                          |

> Note: unlike `search`, `news`, and `videos`, this endpoint has no `time` parameter.

**Example**

```bash
curl -G "https://dashboard.pullbay.com/api/duckduckgo/images" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -d term="wallpaper cat" \
  -d region=us-en \
  -d safeSearch=moderate \
  -d offset=0
```

**Response**

```json
{
  "status": 200,
  "message": "OK",
  "success": true,
  "data": [
    {
      "title": "Wallpaper Cat Photos, Download The BEST Free Wallpaper Cat Stock Photos",
      "image": "https://images.pexels.com/photos/20331914/pexels-photo-20331914.jpeg",
      "thumbnail": "https://tse1.mm.bing.net/th/id/OIP.oOmFm8pcnPy1pVPS46kxfQHaE8?r=0&pid=Api",
      "image_token": "a8b8c30ef6de5362d93dd6f5848ec661ae916727695b7e944138db4a60c5f6ca",
      "thumbnail_token": "036492c962e7830bd485903527a6caf439793418572197fbf6a743a8255f594b",
      "width": 6000,
      "height": 4000,
      "source": "Bing",
      "url": "https://www.pexels.com/search/Wallpaper%20cat/"
    }
  ],
  "pricing": { "creditsCharged": 1 }
}
```

**Response Schema**

| Field                    | Type   | Description                             |
| ------------------------ | ------ | --------------------------------------- |
| `data`                   | array  | Array of [Image objects](#image-object) |
| `pricing.creditsCharged` | number | Credits charged for this request        |

**Credit cost:** dynamic, returned in `pricing.creditsCharged`. No published flat rate.

***

### Search News

Returns news articles for `term`.

**Request**

```bash
GET /duckduckgo/news
Authorization: Bearer YOUR_API_KEY
```

**Parameters**

| Parameter    | Type   | Required | Default | Description                                                                                            |
| ------------ | ------ | -------- | ------- | ------------------------------------------------------------------------------------------------------ |
| `term`       | string | Yes      | —       | Search term, 1–255 characters                                                                          |
| `region`     | string | Yes      | —       | DuckDuckGo region code. Closed list of 63 values — see [Region Codes](#region-codes)                   |
| `safeSearch` | string | Yes      | —       | One of `false`, `moderate`, `strict` — see [Safe Search Levels](#safe-search-levels)                   |
| `offset`     | number | No       | —       | Result offset, 0 or greater                                                                            |
| `time`       | string | No       | —       | Recency filter. One of `a`, `d`, `w`, `m`, `y` — see [Pagination and Recency](#pagination-and-recency) |

**Example**

```bash
curl -G "https://dashboard.pullbay.com/api/duckduckgo/news" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -d term="Marvell Technology" \
  -d region=us-en \
  -d safeSearch=moderate \
  -d time=w
```

**Response**

```json
{
  "status": 200,
  "message": "OK",
  "success": true,
  "data": [
    {
      "title": "Why Marvell Technology Stock Just Dropped",
      "excerpt": "Why Marvell's mad at Poet. Seems somebody let the cat out of the bag too soon...",
      "url": "https://www.fool.com/investing/2026/04/27/why-marvell-technology-stock-just-dropped/",
      "image": "https://g.foolcdn.com/image/?url=https%3A%2F%2Fg.foolcdn.com%2Feditorial%2Fimages%2F867388%2F5-red-stock-market-arrows-pointing-down.jpg",
      "date": 1777303200,
      "relativeTime": "21 hours ago",
      "syndicate": "bing",
      "isOld": false
    }
  ],
  "pricing": { "creditsCharged": 1 }
}
```

**Response Schema**

| Field                    | Type   | Description                                           |
| ------------------------ | ------ | ----------------------------------------------------- |
| `data`                   | array  | Array of [News Article objects](#news-article-object) |
| `pricing.creditsCharged` | number | Credits charged for this request                      |

**Credit cost:** dynamic, returned in `pricing.creditsCharged`. No published flat rate.

***

### Search Videos

Returns video search results for `term`.

**Request**

```bash
GET /duckduckgo/videos
Authorization: Bearer YOUR_API_KEY
```

**Parameters**

| Parameter    | Type   | Required | Default | Description                                                                          |
| ------------ | ------ | -------- | ------- | ------------------------------------------------------------------------------------ |
| `term`       | string | Yes      | —       | Search term, 1–255 characters                                                        |
| `region`     | string | Yes      | —       | DuckDuckGo region code. Closed list of 63 values — see [Region Codes](#region-codes) |
| `safeSearch` | string | Yes      | —       | One of `false`, `moderate`, `strict` — see [Safe Search Levels](#safe-search-levels) |
| `offset`     | number | No       | —       | Result offset, 0 or greater                                                          |

> Note: unlike `search` and `news`, this endpoint has no `time` parameter.

**Example**

```bash
curl -G "https://dashboard.pullbay.com/api/duckduckgo/videos" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -d term="cooking skills" \
  -d region=us-en \
  -d safeSearch=moderate \
  -d offset=0
```

**Response**

```json
{
  "status": 200,
  "message": "OK",
  "success": true,
  "data": [
    {
      "title": "Gordon Ramsay's Top Basic Cooking Skills | Ultimate Cookery Course FULL EPISODE",
      "description": "Gordon Ramsay demonstrates some basic cooking skills as well as some easy to do recipes.",
      "url": "https://www.youtube.com/watch?v=FTociictyyE",
      "image": "https://tse4.mm.bing.net/th/id/OVP.dTE0hC-DCsYuM6UsczwKpgHgFo?pid=Api",
      "duration": "23:03",
      "publishedOn": "YouTube",
      "published": "2019-11-07T17:00:05.0000000",
      "publisher": "Gordon Ramsay",
      "viewCount": 9252292
    }
  ],
  "pricing": { "creditsCharged": 1 }
}
```

**Response Schema**

| Field                    | Type   | Description                             |
| ------------------------ | ------ | --------------------------------------- |
| `data`                   | array  | Array of [Video objects](#video-object) |
| `pricing.creditsCharged` | number | Credits charged for this request        |

**Credit cost:** dynamic, returned in `pricing.creditsCharged`. No published flat rate.

***

## Errors

All non-2xx responses share the same envelope:

```json
{
  "status": 400,
  "message": "Bad request",
  "success": false,
  "error": { "code": "BAD_REQUEST" }
}
```

| Status | Meaning                                  |
| ------ | ---------------------------------------- |
| `400`  | Bad request — missing/invalid parameters |
| `402`  | Insufficient credits                     |
| `404`  | No results found                         |

## Object Schema

### Search Result object

| Field         | Type   | Description                        |
| ------------- | ------ | ---------------------------------- |
| `title`       | string | Page title                         |
| `description` | string | Snippet/summary text from the page |
| `hostname`    | string | Domain the result was served from  |
| `icon`        | string | Favicon URL                        |
| `url`         | string | Link to the page                   |

### Image object

| Field              | Type    | Description                                    |
| ------------------ | ------- | ---------------------------------------------- |
| `title`            | string  | Image title                                    |
| `image`            | string  | Full-size image URL                            |
| `thumbnail`        | string  | Thumbnail image URL                            |
| `image_token`      | string  | Opaque token identifying the full-size image   |
| `thumbnail_token`  | string  | Opaque token identifying the thumbnail         |
| `width` / `height` | integer | Image dimensions in pixels                     |
| `source`           | string  | Originating image search backend (e.g. `Bing`) |
| `url`              | string  | Link to the page hosting the image             |

### News Article object

| Field          | Type    | Description                                                |
| -------------- | ------- | ---------------------------------------------------------- |
| `title`        | string  | Article headline                                           |
| `excerpt`      | string  | Short snippet of the article body                          |
| `url`          | string  | Link to the full article                                   |
| `image`        | string  | Associated image URL                                       |
| `date`         | integer | Publish timestamp, Unix seconds                            |
| `relativeTime` | string  | Human-readable relative publish time (e.g. `21 hours ago`) |
| `syndicate`    | string  | Syndication source (e.g. `bing`)                           |
| `isOld`        | boolean | Whether the article is flagged as stale/older content      |

### Video object

| Field         | Type               | Description                                       |
| ------------- | ------------------ | ------------------------------------------------- |
| `title`       | string             | Video title                                       |
| `description` | string             | Video description                                 |
| `url`         | string             | Link to the video                                 |
| `image`       | string             | Thumbnail/preview image URL                       |
| `duration`    | string             | Video duration, formatted `mm:ss` (or `hh:mm:ss`) |
| `publishedOn` | string             | Hosting platform (e.g. `YouTube`)                 |
| `published`   | string (date-time) | Publish timestamp                                 |
| `publisher`   | string             | Channel or publisher name                         |
| `viewCount`   | integer            | View count                                        |

## Region Codes

`region` is a closed enum, identical across all four endpoints. It is **not** a plain ISO country code — it's a DuckDuckGo-specific region identifier, generally a `<country>-<language>` pair, with a handful of exceptions (`wt-wt` for worldwide/no region, `ct-ca`, `xa-ar`). The API only accepts the 63 values below; any other value is invalid.

**Valid `region` values:**

`wt-wt`, `ar-es`, `au-en`, `at-de`, `be-fr`, `be-nl`, `br-pt`, `bg-bg`, `ca-en`, `ca-fr`, `ct-ca`, `cl-es`, `cn-zh`, `co-es`, `hr-hr`, `cz-cs`, `dk-da`, `ee-et`, `fi-fi`, `fr-fr`, `de-de`, `gr-el`, `hk-tzh`, `hu-hu`, `in-en`, `id-en`, `ie-en`, `il-en`, `it-it`, `jp-jp`, `kr-kr`, `lv-lv`, `lt-lt`, `my-en`, `mx-es`, `nl-nl`, `nz-en`, `no-no`, `pk-en`, `pe-es`, `ph-en`, `pl-pl`, `pt-pt`, `ro-ro`, `ru-ru`, `xa-ar`, `sg-en`, `sk-sk`, `sl-sl`, `za-en`, `es-ca`, `es-es`, `se-sv`, `ch-de`, `ch-fr`, `tw-tzh`, `th-en`, `tr-tr`, `us-en`, `us-es`, `ua-uk`, `uk-en`, `vn-en`

Use `wt-wt` when you don't want to bias results to a specific region. There is no documented default in the spec — `region` is required on every request, so you must pass one of the values above explicitly.

## Safe Search Levels

`safeSearch` is required on all four endpoints and takes one of three values:

* `false` — safe search off. Note that this is the literal boolean-looking token `false`, not a synonym like `off`; in the underlying spec it is written as the unquoted value `false` alongside the two quoted strings below.
* `moderate` — moderate filtering.
* `strict` — strict filtering.

There is no documented default — pass one of the three values explicitly on every request.

## Python Example: Paging Through Web Results with Offset

This example fetches web search results a batch at a time using `offset`, stopping once a batch comes back empty or the requested number of batches has been pulled. There is no `hasNextPage` flag or cursor on this endpoint, so the loop here treats an empty `data` array as the end of results:

```python
import requests

API_KEY = "YOUR_API_KEY"
BASE_URL = "https://dashboard.pullbay.com/api"

def get_search_results(term, region="us-en", safe_search="moderate", batch_size=10, max_batches=5):
    all_results = []
    offset = 0
    for _ in range(max_batches):
        resp = requests.get(
            f"{BASE_URL}/duckduckgo/search",
            headers={"Authorization": f"Bearer {API_KEY}"},
            params={
                "term": term,
                "region": region,
                "safeSearch": safe_search,
                "offset": offset,
            },
        )
        resp.raise_for_status()
        body = resp.json()
        batch = body["data"]
        if not batch:
            break
        all_results.extend(batch)
        offset += len(batch)
    return all_results

results = get_search_results("OpenAI")
print(f"Fetched {len(results)} results")
```

Each request is billed independently, with the charged amount reported in that response's `pricing.creditsCharged` — `offset` is a plain query parameter on this service, not part of Pullbay's `page`/`cursor` pagination envelope used elsewhere, so there's no `pagination` object to inspect for a "next page" flag.

## FAQ

<details>

<summary>What's the difference between <code>region</code> and a country code?</summary>

`region` is a DuckDuckGo-specific identifier, not a plain ISO country code. Most values are `<country>-<language>` pairs (e.g. `us-en`, `uk-en`, `de-de`), but a few don't follow that pattern (`wt-wt`, `ct-ca`, `xa-ar`). It's a closed list of exactly 63 values — see [Region Codes](#region-codes).

</details>

<details>

<summary>Why is <code>safeSearch=false</code> not a boolean?</summary>

`safeSearch` is typed as a string parameter, and one of its three accepted values happens to be the literal token `false` (as opposed to a quoted string like `"off"`). Send it as you would any other enum value for this parameter.

</details>

<details>

<summary>Which endpoints support the <code>time</code> filter?</summary>

Only `search` and `news`. `images` and `videos` do not accept a `time` parameter at all.

</details>

<details>

<summary>How do I get the next page of results?</summary>

Use `offset`. There's no `page`, `cursor`, or `maxItems` parameter on any of these four endpoints — increase `offset` by the number of results you've already consumed to fetch the next batch.

</details>

<details>

<summary>What's the credit cost per request?</summary>

It's dynamic — every response includes `pricing.creditsCharged` with the exact amount for that call. There's no fixed published rate per endpoint or per result.

</details>

<details>

<summary>Can I search without specifying a region?</summary>

No — `region` is a required parameter on all four endpoints. If you don't want to bias results to a particular country or language, pass `wt-wt` (worldwide).

</details>

## Next Steps

* [**API Integration Guide**](broken://pages/68e75ab1a73d266350bd68301be87ff97cad563e) — integrate the Pullbay API into your backend application.
* [**n8n Integration Guide**](broken://pages/4308164455b56bbc694cf74c9768ea689c2fe719) — set up automated workflows using n8n with no coding required.
* [**Services Overview**](broken://pages/0d55376cbcca70097a683a71a593d3077825dbf1) — explore all available Pullbay services.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.pullbay.com/documentation/api-and-references/duckduckgo.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
