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 send | It means |
|---|---|
from=2026-07-09 | 20260709000000 |
to=2026-07-09 | 20260709235959 |
from=2026-07 | 20260701000000 |
to=2026-07 | 20260731235959 |
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
| Question | Range |
|---|---|
| "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.