September 21, 2026

How to Use Date Filters With the You.com Web Search API

How to Use Date Filters With the You.com Web Search API

TLDR: To filter You.com Web Search API results by date, add freshness to the JSON body of POST https://ydc-index.io/v1/search. It accepts day (last 24 hours), week (7 days), month (30 days), year (365 days), or a custom range such as 2026-08-01to2026-08-31. A time phrase in the query can widen the window, so check each result's page_age before trusting it.

This guide covers the date-filtering contract as the Search API reference documents it in September 2026, the questions the docs leave open, and the client-side checks that make a recency filter dependable. It assumes you can already make a request; if not, start with the cURL guide. Two neighboring topics live elsewhere: how index freshness differs from live crawling is in the real-time web search API guide, and scheduled news ingestion is in the news search pipeline guide.

What values does the freshness parameter accept?

The request controls guide documents four keywords and one custom format:

ValueWindow, per the docsGood fit for
dayLast 24 hoursBreaking news, outages, incident status
weekLast 7 daysProduct, market, and competitor monitoring
monthLast 30 daysTrend analysis and research roundups
yearLast 365 daysVersion-sensitive technical questions
YYYY-MM-DDtoYYYY-MM-DDThe dates you nameCalendar periods, retrospectives, evaluations

The last column follows You.com's own guidance: the news results guide says breaking news requires day and trend analysis might use week or month, and the agent guide defaults its coding-search example to year because library answers go stale with each release.

Two details catch people. month and year are rolling windows, not calendar periods: month means the last 30 days whether today is the 3rd or the 30th, so "everything from August" needs a custom range. And the query language has no date operator to fall back on. The documented search operators are site:, filetype:, +, -, AND, OR, and NOT, so freshness is the only documented date control on the endpoint.

A minimal request that prints each result's date next to its URL, across both result sections:

curl -s -X POST https://ydc-index.io/v1/search \
  -H "X-API-Key: $YDC_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"query": "central bank rate decision", "count": 10, "freshness": "week"}' \
  | jq -r '(.results.news // [])[], (.results.web // [])[]
      | "\(.page_age // "no page_age")  \(.url)"'

The // [] guards matter. Both web and news are optional in the response schema, and the endpoint only returns news when its classifier decides the query has news intent.

How do you write a custom date range?

A custom range is two dates joined by a lowercase to with no spaces: 2026-08-01to2026-08-31. Each half uses the YYYY-MM-DD shape that Python's date.isoformat() produces, so build the string from date objects instead of formatting it by hand.

What the docs leave out matters as much as what they specify. As of September 2026, the reference does not say:

  • whether the end date is inclusive;
  • which timezone the boundaries use;
  • which date a web page is matched against: publication, last modification, or indexing;
  • what the server does with a malformed, reversed, or future range.

Treat any claim about those behaviors as an assumption until you have tested it on your own queries. The last gap has a direct consequence for your code. The OpenAPI spec types freshness as one of the four keywords or any string, so a schema validator will not stop 2026-8-1to2026-8-31 or 24h from going out. Validate before you send:

import re
from datetime import date, timedelta

KEYWORDS = {"day", "week", "month", "year"}
RANGE_RE = re.compile(r"^(\d{4}-\d{2}-\d{2})to(\d{4}-\d{2}-\d{2})$")


def freshness_range(start: date, end: date) -> str:
    if start > end:
        raise ValueError("start must be on or before end")
    return f"{start.isoformat()}to{end.isoformat()}"


def validate_freshness(value: str) -> str:
    if value in KEYWORDS:
        return value
    match = RANGE_RE.match(value)
    if not match:
        raise ValueError(f"not a documented freshness value: {value!r}")
    # date.fromisoformat raises on impossible dates such as 2026-02-30
    start, end = (date.fromisoformat(part) for part in match.groups())
    return freshness_range(start, end)


# August 2026, padded one day on each side because boundary handling is undocumented
padded = freshness_range(date(2026, 8, 1) - timedelta(days=1),
                         date(2026, 8, 31) + timedelta(days=1))
print(padded)  # 2026-07-31to2026-09-01

Padding trades precision for coverage. You ask the API for a slightly wider window, then trim to the exact one using each result's date, which the next two sections set up.

Why does a time phrase in the query override freshness?

The reference documents one interaction rule. When the query contains a temporal keyword and you also set freshness, the search uses the broader, less restrictive of the two timeframes. Its example: news this week with freshness set to month runs with month-level freshness. The rule cuts both ways, so a narrow parameter cannot tighten a broad phrase either: chip export news this week sent with day is governed by the week, not the last 24 hours.

The docs do not publish which words count as temporal keywords. this week is the documented example; treat other relative-time phrases such as today, yesterday, or this month, and explicit years, as likely triggers until you have tested them. Two habits prevent the problem:

  • Keep time out of the query when you set freshness. The query carries the topic and the parameter carries the window. If an LLM writes your queries, say so in the tool description, or strip the phrases before the call.
  • Decide who wins when a user types a date phrase. If your interface also has a date picker, map the phrase to a freshness value yourself and remove it from the query, so the API is not silently choosing the broader window for you.

To confirm the rule is biting, run the query with and without the phrase and compare the oldest news page_age in each response. Compare news rather than web results, because only the news date is documented as a publication time, as the next section explains.

What does page_age tell you, and what does it not?

page_age is the only per-result date in the response, and the reference defines it differently for each section:

SectionWhat the reference saysHow to use it
results.newsUTC timestamp of the article's publication dateTreat it as the publication time and parse it as UTC
results.web"The age of the search result"A date the index associates with the page; do not read it as a publication or last-modified date

Three things follow. First, the field is optional on both result types, and the reference's own sample response shows web results with no page_age at all, so any strict filter needs a policy for undated results. Second, the documented values are ISO 8601 strings with no offset, such as 2025-11-25T12:31:29, and some web examples sit at exactly midnight, which suggests day-level precision for those pages. Attach UTC explicitly when you parse, and on Python 3.10 or earlier handle a trailing Z yourself, because datetime.fromisoformat only accepts it from 3.11.

Third, page_age is not a crawl timestamp. It does not tell you when You.com last fetched the page or whether cached text is current. Content freshness is a separate control: extraction.extraction_source on search (blend by default, cache, or fetch, per the page content guide) and max_age on the Contents API. With the default blend source, full-page text for a result inside your window can still come from cache. Nor do the docs promise chronological order, so sort by page_age yourself when order matters.

How do you enforce a strict date window in code?

freshness narrows what the API returns. It does not guarantee that every result falls inside your window, because of the keyword rule, undated web results, and the undocumented boundaries. For anything that feeds an alert, a report, or an evaluation, request with freshness and then filter on page_age yourself. This version uses only the Python standard library and the documented response shape:

import json
import os
import urllib.request
from datetime import datetime, timezone

SEARCH_URL = "https://ydc-index.io/v1/search"


def parse_page_age(value):
    if not value:
        return None
    if value.endswith("Z"):
        value = value[:-1] + "+00:00"  # fromisoformat accepts "Z" only on 3.11+
    try:
        parsed = datetime.fromisoformat(value)
    except ValueError:
        return None
    if parsed.tzinfo is None:  # documented examples carry no offset
        parsed = parsed.replace(tzinfo=timezone.utc)
    return parsed


def search(query, freshness, count=20):
    body = json.dumps({"query": query, "freshness": freshness, "count": count})
    request = urllib.request.Request(
        SEARCH_URL,
        data=body.encode("utf-8"),
        method="POST",
        headers={
            "X-API-Key": os.environ["YDC_API_KEY"],
            "Content-Type": "application/json",
        },
    )
    with urllib.request.urlopen(request, timeout=30) as response:
        return json.load(response)


def strict_window(payload, start, end, keep_undated=False):
    """Split results into kept, outside, and undated. The window is [start, end)."""
    results = payload.get("results") or {}
    report = {"kept": [], "outside": [], "undated": []}
    for section in ("news", "web"):
        for item in results.get(section) or []:
            when = parse_page_age(item.get("page_age"))
            row = {"section": section, "url": item.get("url"), "page_age": when}
            if when is None:
                report["undated"].append(row)
                if keep_undated:
                    report["kept"].append(row)
            elif start <= when < end:
                report["kept"].append(row)
            else:
                report["outside"].append(row)
    return report


payload = search("chip export controls", "2026-07-31to2026-09-01")
report = strict_window(
    payload,
    start=datetime(2026, 8, 1, tzinfo=timezone.utc),
    end=datetime(2026, 9, 1, tzinfo=timezone.utc),
)
print({key: len(rows) for key, rows in report.items()})

Log the three counts on every run. A rising outside count usually means a time phrase crept into the query or the window is wider than you think. A rising undated count means more of your answer depends on web results the filter could not check. Whether to keep undated results is a product call: drop them for alerts and compliance reports, and keep but label them for research, where an undated reference page can still be worth citing.

What should happen when a date window returns nothing?

A tight window on a niche topic can come back empty, and nothing in the response says the filter caused it. Because web and news are optional, treat a missing section and an empty array the same way: as a result, not an error. What you do next depends on whether stale information is worse than none.

def search_with_fallback(query, ladder=("day", "week", "month")):
    for freshness in ladder:
        results = search(query, freshness).get("results") or {}
        if results.get("news") or results.get("web"):
            return freshness, results
    return None, {}

Return the rung that answered and pass it downstream, so a user or a model knows that a "latest news" answer is actually drawn from the last month. Cap the ladder, and skip it for alerting, where a week-old result presented as new is a false alarm. Each rung is another call. At the documented $5.00 per 1,000 calls as of September 2026, a query that misses twice before answering costs $0.015 instead of $0.005. If a job runs 10,000 queries a day and a fifth of them walk the full ladder, that is 4,000 extra calls, or about $20 a day.

Domain filters compound the problem, because a short include_domains allowlist plus a day window is the easiest way to get nothing back. The reference also rejects some combinations outright: include_domains with exclude_domains, or with boost_domains, returns a 422. That is a request bug, not an empty window. In the code above, urlopen raises on any 4xx response, so the ladder never mistakes a 422 for a quiet day.

Should you use a rolling window or a fixed date range?

The tradeoff is relevance against reproducibility. A rolling window like week always reflects the last seven days, which is what monitoring wants, but the same request tomorrow returns a different set, which makes failures hard to reproduce. A fixed range returns the same window every time, which is what evaluations, retrospectives, and regression tests want, at the cost of missing anything published after the end date.

A fixed range pins the window, not the index. Pages can enter or leave an index after your run, so if a test must replay exactly, store the response alongside the query and parameters. When you score a search-backed pipeline, pin freshness to a fixed range so a score change reflects your code rather than the news cycle, the same discipline the web search API evaluation guide applies to benchmarks.

For agents, You.com's evaluation guide advises against exposing freshness in the tool definition unless necessary, so the agent can focus on writing good queries. In practice your code picks the window by route, for example day for status and outage questions and year for version-specific library questions, and the model never sees the parameter.

Does freshness work on GET, the Answer API, and the Research API?

The same values work across You.com's search-backed APIs, but where the field goes differs:

SurfaceWhere freshness goesNotes
Web Search, POST /v1/searchTop-level JSON fieldThe documented path; new features ship on POST only
Web Search, GET /v1/searchQuery string, as in the reference's query=news+this+week&freshness=month exampleStill works but gets no new features; extraction and knowledge are POST-only
Answer API, POST https://api.you.com/v1/answerTop-level JSON fieldAccepts the same freshness, locale, domain, and safesearch controls as search
Research API, POST https://api.you.com/v1/researchInside source_controlSame values; Finance Research does not support source_control
Python SDK, youdotcomFreshness.WEEK and the other enum members, or a range stringThe current 3.5.0 release requires Python 3.10 or later

On the Answer API, freshness restricts the web results the answer is built from, per its search controls guide, so a cited answer is only as current as the window allows. The Answer and Research references repeat the same temporal keyword rule, so the query hygiene above applies to both. For the response shapes, see the AI answer API guide, and for when multi-step research beats one filtered search, the deep research API guide. The Research field itself is documented in the source control guide.

What should you test before relying on a date filter?

Five checks, each a few minutes with a real key, cover the gaps the docs leave open:

  1. Boundary days. Run a one-day range such as 2026-09-20to2026-09-20 on a busy news topic and check whether any news page_age values fall on that date. That tells you how the end date behaves for your queries.
  2. Keyword interaction. Send the same query with and without "this week" at day, and compare the oldest news dates.
  3. Undated share. Log the fraction of web results with no page_age across a sample of production queries. If it is high, a strict filter will throw away much of your recall.
  4. Empty-window rate. Measure how often each window size returns nothing for your real query mix before you set the fallback ladder.
  5. Parameter arrival. Log the exact request body your wrapper sends. A freshness value dropped by a wrapper or serializer produces results that look normal and are silently unfiltered.

If all five pass, a validated freshness value, a query without time phrases, and a page_age post-filter give you a date window you can defend in a report. For the rest of the request surface, the cURL guide linked above covers authentication, pagination, and error handling.

    Share Article:

  1. LI Test

  2. LI Test

Related resources.

How to Use the You.com Web Search API in TypeScript

How to Use the You.com Web Search API in TypeScript

September 22, 2026

Blog

How to Build a News Search Pipeline With the You.com Web Search API

How to Build a News Search Pipeline With the You.com Web Search API

September 22, 2026

Blog

What Is the You.com Web Search API? A Practical Guide for Developers

What Is the You.com Web Search API? Endpoint, Pricing, and Limits

September 22, 2026

Blog

How Authentication Works in the You.com Web Search API

How Authentication Works in the You.com Web Search API

September 21, 2026

Blog

How to Call the You.com Web Search API With cURL

How to Call the You.com Web Search API With cURL

September 21, 2026

Blog