> 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/google-news.md).

# Google News

The Pullbay Google News API provides programmatic access to Google News articles — search by keyword or browse by category. Retrieve article titles, source names, publication timestamps, images, and original article URLs without scraping.

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

## Overview

The Google News service lets you:

* Search Google News by keyword, with optional language/region filtering
* Browse the top articles in a category (Business, Technology, Sports, and more)
* Optionally resolve Google's redirect URLs to direct article URLs

All endpoints are read-only `GET` requests. No Google credentials are required — only your Pullbay API key.

## Common Use Cases

**News Monitoring** — Search a keyword on a schedule to track breaking news, brand mentions, or topic coverage over time.

**Competitive Intelligence** — Monitor news coverage for competitors, products, or industry keywords and surface new articles as they appear.

**Content Aggregation** — Pull top articles by category to populate a news feed, newsletter, or dashboard with fresh content.

**Sentiment & Trend Analysis** — Feed article titles and sources into an NLP pipeline to track how media sentiment around a topic shifts over time.

**Research & Alerting** — Trigger alerts when new articles appear for specific queries (e.g. a company name, a product launch, a regulatory topic).

## Endpoints

| Endpoint                    | Description                     | Pagination             |
| --------------------------- | ------------------------------- | ---------------------- |
| `GET /google-news/search`   | Search articles by keyword      | `maxItems` (bulk only) |
| `GET /google-news/category` | Browse top articles by category | — (full result set)    |

## Search News

Search Google News articles by keyword, with optional language/region and URL resolution.

**Request**

```bash
GET /google-news/search
Authorization: Bearer YOUR_API_KEY
```

**Parameters**

| Parameter      | Type    | Required | Default | Description                                                                                                                                    |
| -------------- | ------- | -------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------- |
| `query`        | string  | Yes      | —       | Search keyword, 1–500 characters                                                                                                               |
| `languageCode` | string  | No       | `US:en` | Language and region code (see [Language Codes](#language-codes)). Defaults to `US:en` (English, United States)                                 |
| `resolveUrl`   | string  | No       | `no`    | `yes` to resolve Google redirect URLs to direct article URLs. Adds a `resolvedUrl` field to each article. `no` returns the raw Google News URL |
| `maxItems`     | integer | No       | 100     | Maximum articles to return, 1–100                                                                                                              |

**Example**

```bash
curl -G "https://api.pullbay.com/google-news/search" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -d query="artificial intelligence" \
  -d languageCode="US:en" \
  -d resolveUrl="no" \
  -d maxItems=20
```

**Python**

```python
import requests

response = requests.get(
    "https://api.pullbay.com/google-news/search",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    params={
        "query": "artificial intelligence",
        "languageCode": "US:en",
        "resolveUrl": "no",
        "maxItems": 20,
    },
)

body = response.json()
print(f"requestId: {body['requestId']}, credits: {body['pricing']['creditsCharged']}")
for article in body["data"]:
    print(f"{article['publishedAt']}  {article['source']}  {article['title']}")
```

**Response**

```json
{
  "requestId": "3b8dcb68-1f8c-4a7b-b9e7-63a7b9986f24",
  "status": 200,
  "message": "OK",
  "success": true,
  "data": [
    {
      "title": "The next phase of the Microsoft-OpenAI partnership",
      "articleUrl": "https://news.google.com/read/CBMimwFBVV95cUxNakYwXzBZNG85QlRVd01tNzEwaEM3djQxWnMya0FN",
      "publishedAt": "2026-04-27T13:07:55Z",
      "imageUrl": "/api/attachments/CC8iK0NnNXdhR2hQYWxjeGIxSmpNMEpOVFJDZk...",
      "source": "The Official Microsoft Blog",
      "sourceIconUrl": "https://encrypted-tbn0.gstatic.com/faviconV2?url=https://blogs.microsoft.com",
      "author": "By Brendan Morrow"
    }
  ],
  "pagination": {
    "page": null,
    "hasNextPage": null,
    "cursor": null,
    "offset": null
  },
  "pricing": { "creditsCharged": 20 }
}
```

**Response Schema**

| Field                    | Type   | Description                                                      |
| ------------------------ | ------ | ---------------------------------------------------------------- |
| `data`                   | array  | Array of [GoogleNewsArticle objects](#googlenewsarticle-object)  |
| `pagination`             | object | All fields are `null` — this endpoint does not paginate          |
| `pricing.creditsCharged` | number | Credits charged for this request (1 credit per article returned) |

**Credit cost:** 1 credit per article returned. A request returning 20 articles costs 20 credits.

## News by Category

Returns the current top articles for a Google News category. Returns up to 300 articles in a single call — no pagination.

**Request**

```bash
GET /google-news/category
Authorization: Bearer YOUR_API_KEY
```

**Parameters**

| Parameter      | Type   | Required | Default | Description                                                                                        |
| -------------- | ------ | -------- | ------- | -------------------------------------------------------------------------------------------------- |
| `category`     | string | Yes      | —       | One of: `business`, `entertainment`, `health`, `latest`, `science`, `sport`, `technology`, `world` |
| `languageCode` | string | No       | `US:en` | Language and region code (see [Language Codes](#language-codes))                                   |

**Example**

```bash
curl -G "https://api.pullbay.com/google-news/category" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -d category="technology" \
  -d languageCode="US:en"
```

**Python**

```python
import requests

response = requests.get(
    "https://api.pullbay.com/google-news/category",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    params={
        "category": "technology",
        "languageCode": "US:en",
    },
)

body = response.json()
print(f"requestId: {body['requestId']}, credits: {body['pricing']['creditsCharged']}")
for article in body["data"]:
    print(f"{article['publishedAt']}  {article['source']}  {article['title']}")
```

**Response**

```json
{
  "requestId": "3b8dcb68-1f8c-4a7b-b9e7-63a7b9986f24",
  "status": 200,
  "message": "OK",
  "success": true,
  "data": [
    {
      "title": "Apple announces new M4 MacBook lineup",
      "articleUrl": "https://news.google.com/read/CBMiaEFVX3lxTE9xUFpDVzNLWWx4Ml9MT0N5NUFtV1...",
      "publishedAt": "2026-04-28T09:15:00Z",
      "imageUrl": "/api/attachments/CC8iK0NnNXdhR2hQYWxjeGIxSmpNMEpOVFJD...",
      "source": "TechCrunch",
      "sourceIconUrl": "https://encrypted-tbn0.gstatic.com/faviconV2?url=https://techcrunch.com",
      "author": null
    }
  ],
  "pagination": {
    "page": null,
    "hasNextPage": null,
    "cursor": null,
    "offset": null
  },
  "pricing": { "creditsCharged": 85 }
}
```

**Response Schema**

| Field                    | Type   | Description                                                                   |
| ------------------------ | ------ | ----------------------------------------------------------------------------- |
| `data`                   | array  | Array of [GoogleNewsArticle objects](#googlenewsarticle-object)               |
| `pagination`             | object | All fields are `null` — this endpoint returns the full result set in one call |
| `pricing.creditsCharged` | number | Credits charged for this request (1 credit per article returned)              |

**Credit cost:** 1 credit per article returned. Up to 300 articles per category.

## Errors

All non-2xx responses use the same envelope:

```json
{
  "requestId": "3b8dcb68-1f8c-4a7b-b9e7-63a7b9986f24",
  "status": 400,
  "message": "Validation failed",
  "success": false,
  "error": { "code": "VALIDATION_ERROR" }
}
```

| Status | Code                          | Cause                                                                    |
| ------ | ----------------------------- | ------------------------------------------------------------------------ |
| `400`  | `VALIDATION_ERROR`            | Missing or invalid parameter (e.g. unknown `category`, `query` too long) |
| `401`  | `AUTHENTICATION_UNAUTHORIZED` | Missing or invalid API key                                               |
| `402`  | `TEAM_INSUFFICIENT_CREDITS`   | Credit balance is 0                                                      |
| `429`  | `RATE_LIMIT_EXCEEDED`         | Request rate exceeded for your plan                                      |
| `5xx`  | —                             | Server-side error — retry with exponential backoff                       |

Failed requests do not consume credits.

## Object Schema

### GoogleNewsArticle object

| Field           | Type              | Description                                                                                                |
| --------------- | ----------------- | ---------------------------------------------------------------------------------------------------------- |
| `title`         | string            | Article headline                                                                                           |
| `articleUrl`    | string            | Google News redirect URL for the article. Resolves to the original publisher URL when `resolveUrl=yes`     |
| `publishedAt`   | string (ISO 8601) | Publication timestamp, e.g. `2026-04-27T13:07:55Z`                                                         |
| `imageUrl`      | string, nullable  | Thumbnail image path or URL. May be a relative path — prepend `https://news.google.com` if needed          |
| `source`        | string            | Publisher name, e.g. `TechCrunch`                                                                          |
| `sourceIconUrl` | string            | URL of the publisher's favicon                                                                             |
| `author`        | string, nullable  | Author byline if present, e.g. `By Jane Smith`. `null` if not available                                    |
| `resolvedUrl`   | string, nullable  | Direct link to the original article — only present when `resolveUrl=yes` was passed on the Search endpoint |

## Language Codes

Both endpoints accept a `languageCode` parameter in `COUNTRY:language` format. The default is `US:en`. There are 84 supported codes covering languages including English, Spanish, French, German, Portuguese, Arabic, Chinese, Japanese, Hindi, and more.

**Examples:**

| Code         | Region                            |
| ------------ | --------------------------------- |
| `US:en`      | English (United States) — default |
| `GB:en`      | English (United Kingdom)          |
| `DE:de`      | German (Germany)                  |
| `FR:fr`      | French (France)                   |
| `ES:es`      | Spanish (Spain)                   |
| `MX:es`      | Spanish (Mexico)                  |
| `BR:pt-419`  | Portuguese (Brazil)               |
| `JP:ja`      | Japanese (Japan)                  |
| `CN:zh-Hans` | Chinese Simplified (China)        |
| `IN:en`      | English (India)                   |
| `AU:en`      | English (Australia)               |
| `CA:en`      | English (Canada)                  |
| `AR:ar`      | Arabic (Saudi Arabia)             |

Pass the exact code string as the `languageCode` parameter value.

## URL Resolution

By default, `articleUrl` is a Google News redirect link (`https://news.google.com/read/...`). These links are valid and open in a browser, but they require a redirect to reach the original article.

Pass `resolveUrl=yes` on the Search endpoint to have Pullbay follow the redirect and return the direct publisher URL in a `resolvedUrl` field alongside the original `articleUrl`:

```json
{
  "title": "The next phase of the Microsoft-OpenAI partnership",
  "articleUrl": "https://news.google.com/read/CBMimwFBVV95cUxNakYwXzBZNG85...",
  "resolvedUrl": "https://blogs.microsoft.com/blog/2026/04/27/microsoft-openai-partnership/",
  "publishedAt": "2026-04-27T13:07:55Z",
  "source": "The Official Microsoft Blog"
}
```

`resolveUrl` is only available on the Search endpoint. The Category endpoint always returns raw Google News redirect URLs.

## Pagination

Neither endpoint supports `page`-by-page pagination.

* **Search** accepts `maxItems` (1–100) to control how many articles are returned in one call. There is no cursor or page mechanism — you receive up to 100 articles per request.
* **Category** always returns the full set of top articles for that category (up to 300) in a single call. There are no pagination parameters.

## Python Examples

### Keyword monitoring loop

Poll a keyword every hour and print new articles since the last run:

```python
import requests
from datetime import datetime, timezone, timedelta

API_KEY = "YOUR_API_KEY"

def fetch_recent_news(query, since_minutes=60):
    body = requests.get(
        "https://api.pullbay.com/google-news/search",
        headers={"Authorization": f"Bearer {API_KEY}"},
        params={"query": query, "maxItems": 100},
    ).json()

    cutoff = datetime.now(timezone.utc) - timedelta(minutes=since_minutes)
    recent = [
        a for a in body["data"]
        if datetime.fromisoformat(a["publishedAt"]) > cutoff
    ]
    print(f"requestId: {body['requestId']}, credits: {body['pricing']['creditsCharged']}")
    print(f"New articles in last {since_minutes} min: {len(recent)}")
    for a in recent:
        print(f"  {a['source']}: {a['title']}")
    return recent

fetch_recent_news("OpenAI")
```

### Fetch top technology news

```python
import requests

body = requests.get(
        "https://api.pullbay.com/google-news/category",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    params={"category": "technology", "languageCode": "US:en"},
).json()

print(f"requestId: {body['requestId']}, credits: {body['pricing']['creditsCharged']}")
for article in body["data"][:10]:
    print(f"{article['publishedAt']}  [{article['source']}]  {article['title']}")
```

### Resolve article URLs

```python
import requests

body = requests.get(
    "https://api.pullbay.com/google-news/search",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    params={"query": "climate change", "resolveUrl": "yes", "maxItems": 10},
).json()

for article in body["data"]:
    url = article.get("resolvedUrl") or article["articleUrl"]
    print(f"{article['title']}\n  {url}\n")
```

## FAQ

<details>

<summary>How often is the data refreshed?</summary>

Articles are fetched from Google News in real time on each request. Results reflect what Google News is currently surfacing for the query or category at the moment of the call. There is no cached snapshot — each request hits Google News live.

</details>

<details>

<summary>What is the maximum number of articles I can get?</summary>

Search returns up to 100 articles per call (`maxItems` 1–100). Category returns up to 300 articles per call. Neither endpoint supports additional pagination beyond these limits.

</details>

<details>

<summary>Why does <code>articleUrl</code> point to <code>news.google.com</code> instead of the publisher?</summary>

Google News wraps all article links in a redirect URL. These links open correctly in a browser. If you need the direct publisher URL for scraping, archiving, or deduplication, pass `resolveUrl=yes` on the Search endpoint — Pullbay will follow the redirect and return the final URL in `resolvedUrl`.

</details>

<details>

<summary>Can I filter by date range?</summary>

There is no server-side date filter. Fetch articles and filter by `publishedAt` in your own code:

```python
from datetime import datetime, timezone, timedelta

cutoff = datetime.now(timezone.utc) - timedelta(hours=24)
recent = [a for a in body["data"] if datetime.fromisoformat(a["publishedAt"]) > cutoff]
```

</details>

<details>

<summary>Does <code>resolveUrl=yes</code> cost extra credits?</summary>

No. URL resolution is included in the standard per-article credit cost. You are charged 1 credit per article returned regardless of whether `resolveUrl` is `yes` or `no`.

</details>

<details>

<summary>What language codes are supported?</summary>

84 codes are supported in `COUNTRY:language` format. The default is `US:en`. Examples include `GB:en`, `DE:de`, `FR:fr`, `JP:ja`, `BR:pt-419`, `CN:zh-Hans`. See [Language Codes](#language-codes) for a full sample list.

</details>
