Endpoints
| Endpoint | Parameters | Response | Cache & fallback |
|---|---|---|---|
GET /api/convert Convert an amount between any two supported currencies at the mid-market cross rate. |
| { amount, from, to, result, rate, date, live, source } | Upstream fetched at most hourly; HTTP cache max-age=300. live:false + static indicative rates if the provider is down. |
GET /api/fx Full USD-based mid-market rate table for every supported currency (~60 codes). | None | { base: "USD", live, updatedAt, rates: { [code]: number } } | Upstream fetched at most hourly; HTTP cache max-age=300. live:false + static indicative rates if the provider is down. |
GET /api/timezone Current local time and DST-aware UTC offset for a coordinate. |
| { live, name, lat, lon, timezone, utcOffsetHours, localTime, dstActive, updatedAt, provider } | One upstream request per coordinate per hour. live:false, provider:"none" — caller falls back to static tzOffset. |
GET /api/weather Current weather, 3-day forecast, sun times and UV for a coordinate via Open-Meteo. |
| { live, name, lat, lon, tempC, feelsLikeC, humidity, windKmh, weatherCode, uvIndex, precipitationMm, forecast, sunrise, sunset, … } | One upstream request per coordinate per 10 minutes. live:false with null weather fields. |
GET /api/country Country facts: Wikipedia summary plus static travel metadata (capital, currency, costs). |
| { live, iso, name, description, extract, flagUrl, coordinates, wikipediaUrl, updatedAt, capital, currency, continent, … } | One upstream request per country per 24 hours. live:false with the static dataset fields still populated. |
Try it — live playground
Pick an endpoint, tweak the parameters and run a real request against the public API. Try an invalid currency code to see the exact error shape your code should handle.
Convert an amount between two currencies at the mid-market rate.
Example requests
curl "https://tripcalc.io/api/convert?from=USD&to=EUR&amount=100"curl "https://tripcalc.io/api/fx"curl "https://tripcalc.io/api/timezone?lat=35.6762&lon=139.6503&name=Tokyo"curl "https://tripcalc.io/api/weather?lat=48.8566&lon=2.3522&name=Paris"curl "https://tripcalc.io/api/country?iso=JP"
Live response samples
GET /api/convert?from=USD&to=EUR&amount=100
{
"amount": 100,
"from": "USD",
"to": "EUR",
"result": 87.7372,
"rate": 0.877372,
"date": "Thu, 24 Sep 2026 00:02:32 +0000",
"live": true,
"source": "tripcalc.io — mid-market rates via open.er-api.com, hourly cache"
}GET /api/fx (truncated)
{
"base": "USD",
"live": true,
"updatedAt": "Thu, 24 Sep 2026 00:02:32 +0000",
"rates": {
"USD": 1,
"EUR": 0.877372,
"GBP": 0.754513,
"JPY": 158.127269,
"THB": 33.366933
}
}The panel fetches the endpoint live in your browser and falls back to the build-time sample if the request fails.
Errors & limits
Client errors always return HTTP 400 with a single JSON field, { error: string }, and Cache-Control: no-store. There are no other 4xx shapes to handle — anything not listed below is a bug.
| Trigger | Status | Body |
|---|---|---|
| GET /api/convert without `to` | 400 | { "error": "Missing required parameter: to" } |
| GET /api/convert?amount=0, negative, non-numeric or > 1,000,000,000 | 400 | { "error": "Invalid amount: must be a number between 0 (exclusive) and 1,000,000,000" } |
| GET /api/convert?from=XXX (unknown code) | 400 | { "error": "Unknown currency code: XXX" } |
| GET /api/timezone or /api/weather without lat/lon | 400 | { "error": "…" } — same { error } shape, message names the missing parameter |
| GET /api/country without iso / unknown ISO code | 400 | { "error": "…" } |
- Rate guidance: ~1 request/second per client. Heavier polling → cache responses (max-age=300) or email us.
amountmust be greater than 0 and at most 1,000,000,000.- Currency codes are ISO 4217 and case-insensitive; only codes in the ~60-currency dataset resolve.
live:falseis not an error — it means cached/indicative data was served (see FAQs).- 5xx responses should not occur; if one does, retry once after a few seconds.
Attribution
Free for public use — if it's useful, link tripcalc.io as the source. Rates are mid-market via open.er-api.com; weather via Open-Meteo; timezones via timeapi.io; country summaries via Wikimedia.
API FAQs
Is there an SLA or usage quota?
No SLA — the API is offered best effort. The upstream providers (open.er-api.com, Open-Meteo, timeapi.io, Wikimedia) are free public services, and our hourly/10-min/24h caches keep upstream load minimal.
How often can I call the API?
Keep it around 1 request per second per client. Responses carry Cache-Control: public, max-age=300, so cache them on your side too.
Does the API work from browsers?
Yes — every endpoint sends Access-Control-Allow-Origin: *, so you can call it directly from client-side JavaScript.
What does live:false mean?
Our upstream provider was unreachable and we served cached or static indicative data instead. Treat live:false values as approximate and re-check later.