This guide provides practical instructions for migrating from News API v2 to v3, with Python code examples for each endpoint.

Prerequisites

Before starting your migration:

  1. Obtain your v3 API token.
  2. Review the API changes v2 vs v3.
  3. Have Python with the requests library installed.

Basic setup

To get started, change authentication and base URLs:

import requests
from typing import Dict, Optional

API_KEY: str = "YOUR_API_KEY"
BASE_URL: str = "https://api.newscatcherapi.com/v2"
HEADERS: Dict[str, str] = {"x-api-key": API_KEY}

def search_news(query: str) -> Optional[Dict]:
    try:
        response = requests.get(
            f"{BASE_URL}/search",
            headers=HEADERS,
            params={"q": query}
        )
        response.raise_for_status()
        return response.json()
    except requests.exceptions.RequestException as e:
        print(f"Error making request: {e}")
        return None

Search endpoint migration

The search endpoint enables news search with enhanced filtering capabilities in v3. Key changes include parameter renaming, updated response fields, and new filtering options.

Parameter changes

1

Rename date parameters

Replace from and to with from_ and to_ respectively:

params = {
    "q": "Tesla",
    "from": "2024/01/01",
    "to": "2024/01/31"
}
2

Update topic to theme

Replace topic with theme and enable NLP:

params = {
    "q": "Tesla",
    "topic": "tech"
}
3

Update search fields

Replace search_in format:

params = {
    "q": "Tesla",
    "search_in": "title_summary"
}

Complete search example

import requests
from typing import Dict, Optional

API_KEY: str = "YOUR_API_KEY"
BASE_URL: str = "https://api.newscatcherapi.com/v2"
HEADERS: Dict[str, str] = {"x-api-key": API_KEY}

def search_articles(
    query: str,
    from_date: str,
    to_date: str,
    topic: str
) -> Optional[Dict]:
    try:
        response = requests.get(
            f"{BASE_URL}/search",
            headers=HEADERS,
            params={
                "q": query,
                "from": from_date,
                "to": to_date,
                "topic": topic,
                "search_in": "title_summary",
                "lang": "en"
            }
        )
        response.raise_for_status()
        data = response.json()

        articles = []
        for article in data.get("articles", []):
            articles.append({
                "title": article.get("title"),
                "url": article.get("link"),
                "source": article.get("clean_url"),
                "published_date": article.get("published_date"),
                "content": article.get("summary")
            })

        return {
            "total_articles": data.get("total_hits", 0),
            "articles": articles
        }

    except requests.exceptions.RequestException as e:
        print(f"Error making request: {e}")
        return None

Usage example

# Search for Tesla news in tech
result = search_articles(
    query="Tesla",
    from_date="2024/01/01",
    to_date="2024/01/31",
    topic="tech"
)

Response structure changes

{
  "status": "ok",
  "total_hits": 521,
  "page": 1,
  "total_pages": 6,
  "page_size": 100,
  "articles": [
    {
      "title": "Tesla lowers range estimates for Model X, S, Y cars",
      "author": "Matt Binder",
      "published_date": "2024-01-05 18:11:03",
      "link": "https://mashable.com/article/tesla-range-estimates",
      "clean_url": "mashable.com", // Domain name, renamed to domain_url in v3
      "excerpt": "The change follows...", // Brief summary, renamed to description in v3
      "summary": "Tesla has updated...", // Full text, renamed to content in v3
      "topic": "tech", // Topic classification, moved to nlp.theme in v3
      "country": "US",
      "language": "en",
      "authors": "Matt Binder",
      "is_opinion": false,
      "twitter_account": "@mashable",
      "_score": 11.959808, // Renamed to score in v3
      "_id": "e623cee7239059b40ca40234" // Renamed to id in v3
    }
  ],
  "user_input": {
    "q": "Tesla",
    "search_in": ["title_summary_en"],
    "lang": ["en"],
    "from": "2024-01-01 00:00:00",
    "to": "2024-01-31 00:00:00",
    "ranked_only": "True",
    "sort_by": "relevancy",
    "page": 1,
    "size": 100,
    "not_sources": [],
    "topic": "tech" // Renamed to theme in v3
  }
}

Latest headlines migration

The latest headlines endpoint provides access to recent news articles. Migration involves similar parameter updates as the search endpoint, with additional time-based filtering options.

Parameter changes

1

Update topic to theme

Replace topic with theme and enable NLP:

params = {
    "topic": "business",
    "countries": "US,GB"
}
2

Time range specification

Optionally specify time range with the when parameter:

params = {
    "countries": "US,GB",
    "when": "24h"  # Optional, defaults to "7d"
}

Complete latest headlines example

import requests
from typing import Dict, Optional

API_KEY: str = "YOUR_API_KEY"
BASE_URL: str = "https://api.newscatcherapi.com/v2"
HEADERS: Dict[str, str] = {"x-api-key": API_KEY}

def get_latest_headlines(
    countries: str,
    topic: str
) -> Optional[Dict]:
    try:
        response = requests.get(
            f"{BASE_URL}/latest_headlines",
            headers=HEADERS,
            params={
                "countries": countries,
                "topic": topic,
                "lang": "en"
            }
        )
        response.raise_for_status()
        data = response.json()

        articles = []
        for article in data.get("articles", []):
            articles.append({
                "title": article.get("title"),
                "url": article.get("link"),
                "source": article.get("clean_url"),
                "published_date": article.get("published_date"),
                "content": article.get("summary")
            })

        return {
            "total_articles": data.get("total_hits", 0),
            "articles": articles
        }

    except requests.exceptions.RequestException as e:
        print(f"Error making request: {e}")
        return None

Usage example

# Get latest business headlines from US and GB
result = get_latest_headlines(
    countries="US,GB",
    topic="business"
)

Additional filtering options

V3 provides enhanced filtering capabilities for latest headlines:

params = {
    "theme": "Business",
    "countries": "US,GB",
    "include_nlp_data": True
    "is_headline": True,          # Filter for homepage articles
    "is_paid_content": False,     # Exclude paywalled content
    "word_count_min": 200,        # Minimum article length
    "word_count_max": 1000        # Maximum article length
}

For a complete list of /latest_headlines parameters, see the Latest headlines reference documentation.

Response structure changes

{
  "status": "ok",
  "total_hits": 10000,
  "page": 1,
  "total_pages": 200,
  "page_size": 50,
  "articles": [
    {
      "title": "Donald Trump Nominates Fox Business Host Sean Duffy",
      "author": "Ted Johnson",
      "published_date": "2024-11-18 23:07:23",
      "published_date_precision": "full",
      "link": "https://deadline.com/2024/11/trump-sean-duffy-1236180738",
      "clean_url": "deadline.com", // Domain name, renamed to domain_url in v3
      "excerpt": "Donald Trump has gone...", // Brief text, renamed to description in v3
      "summary": "Sean Duffy in 2018...", // Full text, renamed to content in v3
      "topic": "business", // Moved to nlp.theme in v3
      "country": "US",
      "language": "en",
      "authors": "Where Img,Class,Display Inline,Ted Johnson",
      "media": "https://deadline.com/wp-content/uploads/2024/11/img.jpg",
      "is_opinion": false,
      "twitter_account": "@tedstew",
      "_score": null, // Renamed to score in v3
      "_id": "75382d1ff5336599bce837ab168bb34b" // Renamed to id in v3
    }
  ],
  "user_input": {
    "lang": ["en"],
    "countries": ["US", "GB"],
    "topic": "business", // Renamed to theme in v3
    "from": "2024-11-11 23:14:24"
  }
}

Sources endpoint migration

The sources endpoint in v3 provides enhanced metadata about news sources. Key changes include the removal of the topic parameter and introduction of new filtering capabilities.

Parameter changes

1

Remove topic parameter

The topic parameter is removed in v3. Instead, use new filtering options:

params = {
    "lang": "en",
    "countries": "US",
    "topic": "news"
}
2

Enable additional metadata

Use include_additional_info to get enhanced source information:

params = {
    "lang": "en",
    "countries": "US"
}

Complete sources example

import requests
from typing import Dict, Optional

API_KEY: str = "YOUR_API_KEY"
BASE_URL: str = "https://api.newscatcherapi.com/v2"
HEADERS: Dict[str, str] = {"x-api-key": API_KEY}

def get_sources(
    countries: str,
    lang: str = "en"
) -> Optional[Dict]:
    try:
        response = requests.get(
            f"{BASE_URL}/sources",
            headers=HEADERS,
            params={
                "countries": countries,
                "lang": lang
            }
        )
        response.raise_for_status()
        data = response.json()

        return {
            "message": data.get("message"),
            "sources": data.get("sources", [])  # List of domain strings
        }

    except requests.exceptions.RequestException as e:
        print(f"Error making request: {e}")
        return None

Usage example

# Get US news sources
result = get_sources(countries="US")

# Access source domains (returns list of strings)
sources = result["sources"]  # e.g., ["example.com", "news.com"]

Advanced filtering options

V3 provides additional parameters for precise source filtering:

params = {
    "lang": "en",
    "countries": "US",
    "include_additional_info": True,
    "source_name": "tech,news",        # Search within source names
    "is_news_domain": True,            # Filter for news domains only
    "news_domain_type": "Original Content",  # Can be "Original Content" or "Aggregator"
    "from_rank": 1,                    # Filter by rank range
    "to_rank": 1000
}

Response structure changes

{
  "message": "Maximum sources displayed according to your plan is set to 1000",
  "sources": [
    // Simple array of domain strings
    "wn.com",
    "yahoo.com",
    "headtopics.com"
    // ...
  ],
  "user_input": {
    "lang": ["en"],
    "countries": ["US"],
    "topic": "news" // Replaced by more specific classification in v3
  }
}

Next steps

  1. Test your migrated implementation.
  2. Review How-to documentation for v3 usage.
  3. Explore News API v3 endpoints for additional capabilities.