no key · no human
For agentsModels › Gemini

Gemini + live news

Native function declarations plus an OpenAI-compatible endpoint. Very large context, which pairs well with reading article bodies in bulk.

VendorGoogle, United States
Base URLhttps://generativelanguage.googleapis.com/v1beta
Model idgemini-2.5-flash
Model credentialGEMINI_API_KEY
Tool formatGemini-native function declarations. An OpenAI-compatible endpoint also exists if you prefer the common shape.
News API keynone required
Vendor docshttps://ai.google.dev/gemini-api/docs/function-calling

Base URLs and model ids change often, and several vendors run separate mainland and international endpoints with non-interchangeable keys. Check the vendor docs above before copying. The part that does not change is the tool itself — our API has no key, no version negotiation and no SDK.

Working example

python
import requests
from google import genai
from google.genai import types

client = genai.Client()        # GEMINI_API_KEY

search_news = types.FunctionDeclaration(
    name="search_news",
    description=("Search worldwide news published in the last 30 days. "
                 "Free, keyless. Use 2-5 keywords, not a question."),
    parameters={
        "type": "OBJECT",
        "properties": {
            "q":    {"type": "STRING"},
            "date": {"type": "STRING", "enum": ["today", "yesterday", "24h", "7d", "30d"]},
            "lang": {"type": "STRING"},
            "size": {"type": "INTEGER"},
        },
        "required": ["q"],
    },
)

IDENT = {"agent_name": "news-agent", "software": "gemini",
         "model": "gemini-2.5-flash"}

cfg = types.GenerateContentConfig(tools=[types.Tool(function_declarations=[search_news])])
chat = client.chats.create(model="gemini-2.5-flash", config=cfg)

r = chat.send_message("What happened with grain exports this week?")
for part in r.candidates[0].content.parts:
    if part.function_call:
        data = requests.get("https://freenewsapi.ai/v1/search",
                            params={**dict(part.function_call.args), **IDENT},
                            timeout=20).json()
        r = chat.send_message(types.Part.from_function_response(
            name="search_news", response={"result": data}))
print(r.text)

Worth knowing about Gemini

  • Native format nests declarations under tools[].function_declarations and returns a functionCall part.
  • An OpenAI-compatible base exists at generativelanguage.googleapis.com/v1beta/openai/ if you would rather reuse the OpenAI snippet.
  • Has its own Google Search grounding. Turn it off when you want news from this corpus specifically, or you will not know which source answered.

Test the tool without the model

Before debugging a tool-calling loop, confirm the data side works. It needs no credentials, so this runs anywhere:

bash
curl "https://freenewsapi.ai/v1/search?q=grain+exports&date=7d&size=5"

If that returns results and your loop still fails, the problem is in the model's tool handling, not in the data.

Prompt it properly

The single most common failure is the model phrasing the query as a sentence. Search is AND across every term, so q=what happened with grain exports matches nothing. Put this in the system prompt:

system prompt
Use search_news for anything about current events or recent developments.
Phrase the query as 2-5 keywords that would appear in a headline, never as a question.
Good: "grain export prices". Bad: "what is happening with grain exports".
Scan titles first. Only request full_text for articles you will actually cite.
If a search returns nothing, drop the least essential keyword and try once more.
No results means no coverage in this corpus \u2014 not that the event did not happen.

More in system prompts.

Same format

Gemini uses the gemini tool-calling shape. These take the same code with a different base URL and model name: none in this list.

← All models · Identify your agent · Token costs