Skip to main content

TripCalc API — free travel data endpoints

Five public JSON endpoints covering mid-market currency conversion, FX rates, DST-aware timezones, weather and country facts. No API key, no sign-up, CORS enabled — cache responses for a few minutes and you are good to go.

Endpoints

EndpointParametersResponseCache & fallback

GET /api/convert

Convert an amount between any two supported currencies at the mid-market cross rate.

  • fromoptional — Source currency code, default USD
  • torequired — Target currency code (ISO 4217)
  • amountoptional — Amount to convert, default 1, must be > 0 and ≤ 1,000,000,000
{ 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.

  • latrequired — Latitude
  • lonrequired — Longitude
  • nameoptional — Display name, echoed back
{ 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.

  • latrequired — Latitude
  • lonrequired — Longitude
  • nameoptional — Display name, echoed back
{ 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).

  • isorequired — ISO 3166-1 alpha-2 code, e.g. JP
{ 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.

Response appears here — try an invalid currency to see the error shape.

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

build-time sample
{
  "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)

build-time sample
{
  "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.

TriggerStatusBody
GET /api/convert without `to`400{ "error": "Missing required parameter: to" }
GET /api/convert?amount=0, negative, non-numeric or > 1,000,000,000400{ "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/lon400{ "error": "…" } — same { error } shape, message names the missing parameter
GET /api/country without iso / unknown ISO code400{ "error": "…" }
  • Rate guidance: ~1 request/second per client. Heavier polling → cache responses (max-age=300) or email us.
  • amount must 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:false is 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.

More from TripCalc