Exact answers
These are small GET endpoints for things that are easy to get wrong. No key is needed.
Every endpoint answers in plain text. The first line is the answer and the lines after it are details.
Add format=json to get JSON instead. The JSON has an answer field plus one field per detail line, and money amounts are strings so their decimals stay exact. Errors look like {"error": "..."}.
Conventions:
- Dates are
YYYY-MM-DD. - Local times are
YYYY-MM-DDTHH:MM, optionally with:SS. - Time zones are IANA names such as
Europe/Brussels, orUTC. - Countries are ISO 3166-1 alpha-2 codes such as
BEorUS. Holidays are national public holidays only. Bank holidays, regional holidays and observances are not included. Holiday names are given in English. - Text is normalised to NFC before counting. A "character" is a grapheme cluster, meaning what a human sees as one character.
- Errors:
- HTTP 400 with a line saying what's wrong.
- HTTP 413 when input is over a limit. Input is never truncated.
- HTTP 414 when the URL is longer than 8 KB.
/x/now
Returns the current date and time.
tz: optional, defaults toUTC.
GET /x/now?tz=Europe/Brussels 2026-10-27T21:14:05+01:00 date: 2026-10-27 weekday: Tuesday time: 21:14:05 utc_offset: +01:00 tz: Europe/Brussels unix: 1793132045
/x/days
Returns the number of calendar days from from to to. The result is negative if to is earlier than from.
GET /x/days?from=2026-01-01&to=2026-12-31 364 from: 2026-01-01 (Thursday) to: 2026-12-31 (Thursday)
/x/workdays
Counts the dates from from to to that are Monday to Friday and not national public holidays in country. Both ends are included. to must not be earlier than from, and the span can be at most 3,660 days.
GET /x/workdays?from=2026-11-01&to=2026-11-30&country=BE 20 from: 2026-11-01 (Sunday), to: 2026-11-30 (Monday), both inclusive country: BE holidays on weekdays in range: 2026-11-11 Armistice Day
/x/add
Adds days calendar days to date. days can be negative, up to ±3,660.
With workdays=1 and a country, it adds that many business days instead, skipping weekends and national public holidays. The starting date itself is never counted. days=0 returns date unchanged.
GET /x/add?date=2026-12-24&days=1&workdays=1&country=BE 2026-12-28 weekday: Monday skipped: 2026-12-25 Christmas Day (holiday), 2026-12-26 to 2026-12-27 (weekend)
/x/tz
Converts a local time in time zone from to time zone to.
If time carries an explicit offset or Z, from is optional.
Some local times don't exist, because the clock jumps forward for daylight saving time. These are moved forward by the length of the gap. Other local times happen twice, when the clock goes back; these use the earlier one. In both cases the response adds a note: line saying so.
GET /x/tz?time=2026-10-27T15:00&from=Europe/Brussels&to=America/New_York 2026-10-27T10:00:00-04:00 from: 2026-10-27T15:00:00+01:00 (Europe/Brussels) to: 2026-10-27T10:00:00-04:00 (America/New_York) difference: -5:00
/x/fx
Converts amount from one currency to another, using the European Central Bank's euro reference rates.
from,to: currencies the ECB publishes, plusEUR. An unsupported code returns 400 with the list of supported codes. Pairs that don't involve the euro are calculated through EUR at full precision.date: optional, defaults to the latest rate. On days without a rate, such as weekends and TARGET holidays, the most recent earlier rate is used, andrate_datesays which day that was. Dates before 1999-01-04 or after the latest stored rate return 400.- Rounding: the result is rounded half-up to 2 decimals. The rate is shown as the ECB publishes it for pairs involving EUR, and to 6 decimals for cross rates.
- Answers come only from the stored ECB history, which is refreshed daily. A request never triggers a live fetch.
- The ECB publishes these rates for information purposes only.
GET /x/fx?amount=100&from=EUR&to=USD&date=2026-10-26 111.88 100 EUR = 111.88 USD rate: 1 EUR = 1.1188 USD rate_date: 2026-10-26 source: European Central Bank euro foreign exchange reference rates
/x/count
Counts what's in text. The text can be up to 4,000 characters and up to 16,000 bytes in UTF-8.
- Use GET for short text. For long text, or text with many non-ASCII characters, POST it as a form or as JSON:
{"text": "...", "char": "r"}. Request bodies can be up to 64 KB, which is enough for the full limit in any encoding. characterscounts grapheme clusters, after NFC normalisation.letterscounts grapheme clusters whose first code point is a Unicode letter.wordscounts Unicode word segments that contain a letter or a digit.- With
char(one character), the first line is the number of times it occurs.- The match is case-sensitive by default.
- With
ignore_case=1, both sides are lowercased using Unicode default case conversion before matching.
More examples:
efollowed by U+0301 (a combining accent), thente: 3 characters, 3 letters, 1 word.- 👍🏽 (thumbs up with a skin-tone modifier): 1 character, 0 letters, 0 words.
GET /x/count?text=strawberry&char=r 3 occurrences of "r": 3 characters: 10 letters: 10 words: 1
The text parameter is never stored or logged.