Date API for developers and AI agents
Date arithmetic is where language models and scripts quietly go wrong: business days across a border, a holiday that moved because it fell on a Sunday, a countdown computed in the server's timezone instead of the user's. tilwhen answers those over plain HTTP, and every answer arrives with its own working.
No key, no account, no quota. Every endpoint is a public
GET returning JSON, with Access-Control-Allow-Origin: * so it
works from a browser. Requests are rate limited per IP at 300 per
60 seconds; above that you get a 429 with
Retry-After. Machine-readable spec:
openapi.json (OpenAPI 3.1).
Using an AI client? The same engine is hosted as a Model Context
Protocol server at https://mcp.tilwhen.com/mcp, so Claude, Cursor and any other MCP
client can call it directly with no key and nothing to install.
Set up the MCP server.
Try it
curl "https://tilwhen.com/api/v1/business-days?date=today&days=30&cal=GB&tz=Europe/London" Answers a plain-English question the same way:
curl "https://tilwhen.com/api/v1/parse?q=90+business+days+from+today+excluding+uk+holidays" A link you can construct from the question
If you are an assistant handing a person a link rather than calling an endpoint, put the
question straight in the path. /ask/<question-in-hyphens> resolves to
whichever page already answers it, so you never have to know the route table:
https://tilwhen.com/ask/90-business-days-from-today-excluding-uk-holidays
→ 302 /business-days-calculator?n=90&dir=from&cal=GB
https://tilwhen.com/ask/days-until-2026-12-25
→ 302 /days-until/christmas
ISO dates survive the hyphens. Send Accept: application/json (or add
?format=json) and you get the parsed operation, the answer, the receipt and the
URL to cite instead of a redirect. Anything the parser cannot place confidently lands on the
homepage with the question loaded into the command palette rather than guessing.
These URLs are noindex and absent from the sitemap on purpose: they redirect to
real pages rather than being pages, so they resolve for people without spending crawl budget.
Link people to /ask/...; cite the page it resolves to.
Endpoints
Parameters marked * are required.
| Endpoint | What it answers | Parameters |
|---|---|---|
/api/v1/parse | Parse a natural-language date query and answer it | q* tz locale |
/api/v1/add | Date N calendar days after a date | date days* tz |
/api/v1/subtract | Date N calendar days before a date | date days* tz |
/api/v1/diff | Signed whole days between two dates (exclusive) | from* to* tz |
/api/v1/business-days | Business days between two dates, or the date N business days from a date | from to date days dir cal custom ww tz |
/api/v1/invoice-due | Invoice due date from net payment terms | date net* roll cal custom ww tz |
/api/v1/next-occurrence | Next occurrence of a tracked event or weekday, strictly after the base date | event weekday from tz |
/api/v1/holidays | Observed public holidays for a jurisdiction and year | cal* year* |
/api/v1/explain | Full receipt plus human-readable derivation steps for any operation | op* |
Every answer carries its working
Responses are { answer, receipt }. The receipt names the normalized
operation, the pinned input dates, the IANA timezone, the counting convention (whole
calendar days, today = day 0, exclusive), the working week, the holiday calendar with each
excluded holiday itemised, the primary sources with their retrieval dates, the engine and
dataset versions, and a stable result ID. The ID is a deterministic hash of
the normalized inputs and versions, with the timestamp deliberately excluded, so the same
question under the same versions always reproduces the same ID. Engine 1.0.0,
holiday dataset 2026.07.2. See how to cite a result.
Holiday calendars
Pass cal= one of: US, GB, GB-SCT, GB-NIR, IE, FR, CA, AU, UG.
There is deliberately no default: omit it and no holidays are excluded, and
the receipt says so rather than guessing from your timezone or IP. Supply your own
organisation's calendar instead with custom= as comma-separated ISO dates.
Working week is ww= (mon-fri, sun-thu,
mon-sat).
Errors, caching and conventions
- Errors are always JSON, never HTML:
{"error":{"code":"...","message":"..."}}with a specific code such asinvalid_date,unknown_jurisdiction,out_of_rangeorrate_limited. - Unrecognised values are rejected rather than silently defaulted.
roll=yesis a400, not a quiet "no". - Answers pinned to explicit dates are immutable: they carry an
ETagand honourIf-None-Matchwith a304. - Answers relative to "today" expire at the next midnight in the requested timezone, via
s-maxage. tz=takes any IANA identifier and defaults toUTC. It is the only thing that decides which calendar day "today" is.- Only
GET,HEADandOPTIONS; anything else is a405.
Model Context Protocol
If you are wiring this into an AI client rather than calling it from code, the same engine is exposed over MCP with the same receipts. See the MCP server.
Using it
The API is free and unmetered below the rate limit, and there is no plan to change that. Attribution to tilwhen.com is welcome but not required. If you are building something that needs a higher limit or a jurisdiction we do not cover yet, get in touch.