Authentication

Every API call needs a key. Two ways to get one:

Quotas: the free plan allows 100 calls/day per key across all endpoints. Over-quota calls return 429 { "error": "quota_exceeded" }. Missing/invalid keys return 401. All errors are JSON: { "error": "<code>", "message": "<detail>" }.

OpenAPI 3.1 specs: businessdays.yaml · emailcheck.yaml · currency.yaml — import them into Postman, Insomnia, or your codegen.

API 1 — Business Days & Holidays

Coverage: 49 countries, years 2024–2030. Weekends default to Saturday/Sunday; Egypt, Israel and Saudi Arabia observe Friday/Saturday; the UAE observes Saturday/Sunday. Dates outside coverage return 422 date_out_of_coverage — the API never guesses.

GET /v1/businessdays/countries

List supported country codes, names, and covered years. No parameters.

GET /v1/businessdays/holidays

ParameterRequiredNotes
countryyesISO 3166-1 alpha-2, e.g. US, DE, JP
yearyes2024–2030
GET /v1/businessdays/holidays?country=US&year=2026
{
  "country": "US", "year": 2026, "count": 12,
  "holidays": [
    { "date": "2026-01-01", "name": "New Year's Day" },
    { "date": "2026-07-03", "name": "Independence Day (substitute day)" },
    ...
  ]
}

GET /v1/businessdays/is-business-day

ParameterRequiredNotes
countryyesalpha-2 code
dateyesYYYY-MM-DD

Returns weekday, is_weekend, is_holiday, holiday_name (or null), and is_business_day.

GET /v1/businessdays/add

ParameterRequiredNotes
countryyesalpha-2 code
dateyesstart date; the start date itself is not counted
daysyesinteger, negative moves backwards, |days| ≤ 3660
GET /v1/businessdays/add?country=US&date=2026-07-01&days=2
{ "country": "US", "start_date": "2026-07-01", "days": 2, "result_date": "2026-07-06" }

GET /v1/businessdays/count

ParameterRequiredNotes
countryyesalpha-2 code
fromyesYYYY-MM-DD
toyesYYYY-MM-DD; a reversed range returns a negative count
inclusivenodefault true; false = end-exclusive

GET /v1/businessdays/next

Parameters: country, date, optional direction (1 default, or -1). Returns the next business day strictly after (or before) the given date as result_date.

API 2 — Email Checker-Plus

GET|POST /v1/email/check

GET with ?email=..., or POST a JSON body { "email": "..." }. A syntactically invalid address returns HTTP 200 with valid: false and a machine-readable reason — a check result is data, not an error.

GET /v1/email/check?email=someone@mailinator.com
{
  "email": "someone@mailinator.com",
  "valid": false,
  "syntax_valid": true,
  "local_part": "someone",
  "domain": "mailinator.com",
  "is_disposable": true,
  "is_role_account": false,
  "has_mx": true,
  "mx_records": ["..."],
  "reason": "disposable_domain"
}

Checks performed: syntax (practical RFC 5322 subset), disposable domain (121,570-entry open list), role account (admin@, support@, postmaster@, …), MX existence via DNS-over-HTTPS with A-record fallback (RFC 5321 §5.1). Addresses are never stored.

API 3 — Currency Conversion

Rates: ECB euro reference rates, refreshed on ECB business days. They are indicative reference rates, not transaction rates; every response repeats that disclaimer.

GET /v1/fx/currencies

Supported currency codes and the current rate date.

GET /v1/fx/rates

ParameterRequiredNotes
basenodefault EUR; any supported currency — rates are rebased to units per 1 base

GET /v1/fx/convert

ParameterRequiredNotes
fromyesISO 4217 code
toyesISO 4217 code
amountyesnumber
GET /v1/fx/convert?from=EUR&to=USD&amount=100
{
  "from": "EUR", "to": "USD", "amount": 100,
  "result": 107.72, "rate": 1.0772, "date": "2026-10-23",
  "disclaimer": "ECB euro reference rates: indicative, published for reference only, not transaction rates."
}