Skip to content
unzoi docs

Time windows

from and to are the two parameters that most change what a request costs and what it returns. Everything else is a filter.

Format

Both accept 2026-07-09 or 20260709120000, and any digit grouping in between. They are normalised to 14-digit YYYYMMDDHHMMSS in UTC, with from padded to the start of the period you named and to to the end:

You sendIt means
from=2026-07-0920260709000000
to=2026-07-0920260709235959
from=2026-0720260701000000
to=2026-0720260731235959

So from=2026-07-09&to=2026-07-09 is that whole day, which is almost always what you meant.

Why omitting from is expensive

The corpus is partitioned by time, and each partition is served independently — that is what lets the archive be enormous without every query paying for its size. A query is routed only to the partitions its range overlaps.

Relevance ranking has no shortcut across those partitions: an article from 2003 can out-score one from this morning, so a ranked query has to visit every partition overlapping its range. With no range, that is all of them.

Your plan bounds it too

Every plan has an archive depth. A from older than yours is pulled forward rather than refused, and the response says so:

{ "history_days": 30, "from_clamped": true, "results": [...] }

from_clamped: true is the difference between "my plan stopped here" and "there is no coverage". Read it — see Archive depth.

Picking a range

QuestionRange
"What is happening?"Omit both, or from = a few hours ago. Use /top-headlines.
"What happened this week?"from = 7 days ago.
"How was this covered when it broke?"A tight window around the event — a day or two.
"How has coverage changed over a year?"Several requests, one per month, rather than one request spanning the year.

That last row is the one people get wrong. A year-long relevance query is slow, may time out, and returns a single ranked list that tells you nothing about change. Twelve monthly queries are faster individually, likelier to succeed, and give you a series:

for month in 01 02 03 04 05 06 07 08; do
  total=$(curl -s -G "https://api.unzoi.com/stories" -H "x-api-key: $UNZOI_KEY" \
    --data-urlencode "q=port congestion" \
    --data-urlencode "from=2026-$month" \
    --data-urlencode "to=2026-$month" \
    --data-urlencode "limit=1" | jq -r '.total')
  echo "2026-$month  $total stories"
done

When a wide query times out

A 408 means the request exceeded the server's own budget while walking partitions. The fix is a narrower window, not a longer client timeout — the work is proportional to the range.

A very wide query may also return 200 with a partial answer, having reached most of its partitions inside the budget. If completeness matters, narrow it so the whole thing fits.

Published, not mentioned

from/to filter on publication time. An article published today can be about a date next year — that is what mentioned_date is for, and the two are genuinely different questions.