no key · no human
HomeNews API for AI agentsIdentify your agent

Tell us who you are

There is no API key here and there never will be. But if you send one optional header saying what your agent is and what it runs through, you make it much more likely that it stays that way.

Entirely optional. Nothing is rejected, throttled or degraded if you send nothing. There is no registration behind it, no value to obtain from us, and no validation — you make the string up yourself. It is a courtesy, not a credential.

The header

recommended
X-Agent: agent_name=newsbot; version=1.4.2; software=langchain/0.3; model=gpt-4o; purpose=rag; contact=https://example.com/bot

One header, semicolon-separated key=value pairs. Every key is optional, including all of them. Send two if two is all you have:

minimum worth sending
X-Agent: agent_name=my-research-bot; software=n8n

Recognised keys

Unknown keys are kept as-is and ignored, so you can invent your own without breaking anything, and we can add new ones without breaking you.

KeyExampleWhy it helps
agent_namenewsbotWhat your agent is called. The one key worth sending if you send only one.
version1.4.2Your version. Lets us tell a regression in your build from a regression in ours.
softwarelangchain/0.3The program or library the agent runs through: langchain, llamaindex, n8n, zapier, claude-desktop, claude-code, cursor, openai-assistants, crewai, autogen, dify, flowise, semantic-kernel, custom. Add a version after a slash if you like.
modelgpt-4oWhich model is driving the agent. Different models phrase queries very differently, and that shapes what we tune.
provideropenaiWho serves the model: openai, anthropic, google, mistral, local.
mcpclaude-desktopThe MCP client, if the call arrives through Model Context Protocol rather than direct HTTP.
purposeragWhat the calls are for: rag, monitoring, research, digest, alerting, dataset, eval.
orgexample-labsYour company or project, if you are happy to say.
contacthttps://example.com/botA URL or mailto: where we can reach a human. The only key we would ever act on individually.
sessiona91f3cAn opaque id that groups the calls of one run together. Make it random. Never put a user id, an email or anything personal here.
sdkpython/3.12Language and runtime of your client.

Also send a User-Agent

If you set nothing else, set this. It is the standard mechanism, every HTTP client supports it, and it is the convention Wikimedia and other large public services already ask of automated clients:

standard
User-Agent: newsbot/1.4.2 (+https://example.com/bot)

Default library user agents — python-requests/2.32, node-fetch, Go-http-client/2.0 — tell us a language and nothing else. That is not a problem, it is just a missed opportunity.

Or pass it as query parameters

Equally good, and often easier: a browser fetch from a page you do not control, a no-code tool with a fixed request shape, a shell one-liner. Unknown parameters are ignored by the API, so this is safe on every endpoint and cannot break a request:

bash
curl "https://freenewsapi.ai/v1/search?q=climate&agent_name=newsbot&software=n8n&model=gpt-4o&purpose=digest"

The parameter names mirror the header keys one for one: agent_name, software, model, version, purpose, contact. Send the two that matter — agent_name and software — and skip the rest.

Every model integration page ships this already filled in for that model.

In code

Python

python
import requests

AGENT = {
    "User-Agent": "newsbot/1.4.2 (+https://example.com/bot)",
    "X-Agent": "agent_name=newsbot; version=1.4.2; software=langchain/0.3; "
               "model=gpt-4o; purpose=rag; contact=https://example.com/bot",
}

r = requests.get("https://freenewsapi.ai/v1/search",
                 params={"q": "climate summit", "date": "24h", "size": 10},
                 headers=AGENT, timeout=20)

JavaScript

javascript
const AGENT = {
  "User-Agent": "newsbot/1.4.2 (+https://example.com/bot)",
  "X-Agent": "agent_name=newsbot; version=1.4.2; software=custom; model=claude-opus-5; purpose=rag",
};

const r = await fetch("https://freenewsapi.ai/v1/search?q=climate&size=10",
                      { headers: AGENT });

Browsers refuse to let page scripts override User-Agent. From a browser, send X-Agent only, or use the query-parameter form above.

curl

bash
curl -H "X-Agent: agent_name=newsbot; software=cursor; model=claude-opus-5" \\
     -A "newsbot/1.4.2 (+https://example.com/bot)" \\
     "https://freenewsapi.ai/v1/search?q=climate&size=5"

LangChain tool

python
import requests
from langchain_core.tools import tool

SESSION = requests.Session()
SESSION.headers.update({
    "User-Agent": "research-agent/2.0 (+https://example.com)",
    "X-Agent": "agent_name=research-agent; version=2.0; software=langchain/0.3; "
               "model=gpt-4o; purpose=research",
})

@tool
def search_news(q: str, date: str = "7d", size: int = 10) -> list:
    """Search worldwide news from the last 30 days."""
    return SESSION.get("https://freenewsapi.ai/v1/search",
                       params={"q": q, "date": date, "size": size},
                       timeout=20).json()["results"]

Set it once on a session object and every call inherits it. That is the whole integration cost.

Why we ask

It is what keeps keys away

The usual reason an open API closes is that its operators cannot see who is using it, so the only lever left when something goes wrong is authentication. Voluntary identification gives us the visibility without the wall. Every agent that identifies itself is an argument against ever needing a key.

We can warn you before we break you

If a change would affect the way your agent queries, a contact means we can tell you first instead of you finding out from a failing job.

We tune for what is actually used

Knowing that most traffic arrives from, say, n8n workflows asking for date=today tells us exactly what to cache and what to optimise. Right now we are guessing.

Abuse gets handled surgically

When one caller floods the service, the blunt response is a rule for everyone. An identified caller can be contacted, or given its own allowance, while everyone else is left alone.

What identifying will get you later

None of this exists yet, and none of it is a reason to identify today — but this is the direction, so you know why the header is worth wiring in now rather than later:

  • Higher burst allowance for identified agents, once there is a reason to differentiate at all.
  • Change notices ahead of time, to the contact you gave.
  • A public list of agents using the service, opt-in, with a link back to yours. Visibility in exchange for visibility.
  • Usage insight for your own agent — what it asked for, how often it got nothing back, which queries wasted tokens.

What we will never do with it

  • Require it. An anonymous request stays a first-class request. That is the point of the whole service.
  • Validate it. There is nothing to register and nothing to verify. Two agents may call themselves the same thing; we do not care.
  • Sell it or share it. It stays in our operational logs.
  • Use it to price you. Free keyless search is permanent, identified or not.

Do not put personal data in the header. No end-user names, emails, IDs or query context. session exists for grouping calls and should be a random string. contact should reach an operator, not a user. Treat the header as public: it travels through a CDN and lands in access logs.

Check what arrives

Send the header and it lands in our access log alongside the request. There is nothing to confirm and no response header to read — a request with the header and one without get identical responses, which is exactly the guarantee being made here.

bash
curl -H "X-Agent: agent_name=test-bot; software=curl" \\
     "https://freenewsapi.ai/v1/search?q=test&size=1"

Related

OpenAI tool definition · Anthropic tool definition · Rate limits · Privacy