A paid search call shouldn't die on a quota error
Agents call web-search when they need current links before they read, compare, or cite. A recent buyer was making the same Bitcoin market query throughout the day. The query was valid, payment settled, and the primary search path answered with a rate limit.
Retrying didn't help. Account-level quota failures don't clear after a one-second delay, so three attempts only made the response slower. Some calls took more than ten seconds before returning the same error.
That path has changed.
What the response looks like now
web-search still returns ranked primary search results when they're available. A successful response has the same query, results, source, and include_text fields as before. It now also carries degraded: false.
When primary search returns a quota error, the endpoint makes one bounded request for recent public-news results. If that succeeds, the paid call returns 200 with degraded: true and a direct note:
{
"query": "bitcoin market sentiment funding rate BTC today",
"results": [
{
"rank": 1,
"title": "Recent Bitcoin market coverage",
"url": "https://example.com/story",
"snippet": "20260721T180000Z · neutral",
"domain": "example.com"
}
],
"source": "GDELT public-news fallback",
"source_url": "https://www.gdeltproject.org/",
"degraded": true,
"include_text": false,
"note": "Primary web search was unavailable; returned recent public-news results instead."
}
The distinction matters. Recent news from GDELT is useful for current market questions, company monitoring, and event research, but it isn't a full web index. The fallback is best-effort, and its recency is capped at seven days even when a request asks for month, year, or any. A Google site: filter is translated to GDELT's domain: filter, so only news-indexed pages from that domain can appear. The response says exactly what happened so an agent can decide whether to continue, wait, or call a narrower endpoint.
If both paths fail, the endpoint returns the original dependency status. It doesn't turn an outage into an empty success.
Repeat queries skip the upstream call
Successful non-empty results are cached for 15 minutes. If the primary path later fails, the last good result remains eligible as a stale fallback for six hours. Empty or malformed responses never enter the cache.
This helps scheduled agents that ask the same question every few minutes. The first good call pays the latency cost. Nearby repeat calls get the same ranked result without another provider request.
The cache key includes normalized query text, recency, and result limit. A request for three results won't collide with a request for ten.
Failure alerts now reach the operator
Search quota and credential failures also enter the operator alert path. The dashboard groups repeated failures for 30 minutes and sends a Telegram message with the endpoint, status, and next action. A 429 says to check or top up the account quota. A 401 or 403 says to refresh the API credentials.
Agents get a bounded fallback. The operator gets the account-level fix before the next batch of paid calls arrives.