{"openapi":"3.1.0","info":{"title":"ad-bs — AD ⇄ BS date API","version":"1.0.0","description":"Read-only, unauthenticated API over a manually curated Gregorian (AD) ⇄ Bikram Sambat (BS) mapping of 81,919 days (1920-01-01 AD … 2144-04-13 AD). All responses use the envelope { ok, data } or { ok, error, message }."},"servers":[{"url":"https://annodomini-bikramsambat.ajam.dev"}],"paths":{"/api/v1/convert":{"get":{"summary":"Convert a date between AD and BS","parameters":[{"name":"ad","in":"query","required":false,"schema":{"type":"string"},"description":"AD date. Lenient: YYYY-MM-DD, YYYYMMDD, YYYY_MM_DD, YYYY/MM/DD, with optional time portion (stripped), e.g. 2026-07-09T13:45:00"},{"name":"bs","in":"query","required":false,"schema":{"type":"string"},"description":"BS date. Lenient: YYYY-MM-DD, YYYYMMDD, YYYY_MM_DD, YYYY/MM/DD, with optional time portion (stripped), e.g. 2026-07-09T13:45:00. Provide exactly one of ad/bs."}],"responses":{"200":{"description":"the full mapping entry","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"data":{"type":"object","properties":{"id":{"type":"integer","description":"Stable row id (days since 1920-01-01, 1-based)"},"ad":{"type":"string","format":"date","description":"Gregorian date, YYYY-MM-DD"},"bs":{"type":"string","description":"Bikram Sambat date, YYYY-MM-DD"},"day":{"type":"string","description":"Weekday name (shared by both calendars)"},"day_of_week":{"type":"integer","minimum":0,"maximum":6,"description":"0=Sunday .. 6=Saturday"},"ad_human":{"type":"string","example":"Thursday, 9th July - 2026 AD"},"bs_human":{"type":"string","example":"Thursday, 25th Ashad - 2083 BS"},"ad_month_name":{"type":"string"},"bs_month_name":{"type":"string"},"divergence":{"type":"object","description":"Component-wise offset. AD + ad_to_bs = BS; bs_to_ad is its negation.","properties":{"ad_to_bs":{"type":"string","example":"+56y 8m 16d"},"bs_to_ad":{"type":"string","example":"-56y 8m 16d"}}}}}},"required":["ok","data"]}}}},"400":{"description":"invalid input (bad date shape, missing/duplicate params, unknown tz)","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":false},"error":{"type":"string","description":"machine-readable slug"},"message":{"type":"string","description":"human-readable explanation"}},"required":["ok","error"]}}}},"404":{"description":"valid input outside the dataset range","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":false},"error":{"type":"string","description":"machine-readable slug"},"message":{"type":"string","description":"human-readable explanation"}},"required":["ok","error"]}}}}}}},"/api/v1/today":{"get":{"summary":"Today's entry","parameters":[{"name":"tz","in":"query","required":false,"schema":{"type":"string","default":"Asia/Kathmandu"},"description":"IANA timezone name or +HH:MM offset"}],"responses":{"200":{"description":"today's mapping entry","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"data":{"type":"object","properties":{"id":{"type":"integer","description":"Stable row id (days since 1920-01-01, 1-based)"},"ad":{"type":"string","format":"date","description":"Gregorian date, YYYY-MM-DD"},"bs":{"type":"string","description":"Bikram Sambat date, YYYY-MM-DD"},"day":{"type":"string","description":"Weekday name (shared by both calendars)"},"day_of_week":{"type":"integer","minimum":0,"maximum":6,"description":"0=Sunday .. 6=Saturday"},"ad_human":{"type":"string","example":"Thursday, 9th July - 2026 AD"},"bs_human":{"type":"string","example":"Thursday, 25th Ashad - 2083 BS"},"ad_month_name":{"type":"string"},"bs_month_name":{"type":"string"},"divergence":{"type":"object","description":"Component-wise offset. AD + ad_to_bs = BS; bs_to_ad is its negation.","properties":{"ad_to_bs":{"type":"string","example":"+56y 8m 16d"},"bs_to_ad":{"type":"string","example":"-56y 8m 16d"}}}}}},"required":["ok","data"]}}}},"400":{"description":"invalid input (bad date shape, missing/duplicate params, unknown tz)","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":false},"error":{"type":"string","description":"machine-readable slug"},"message":{"type":"string","description":"human-readable explanation"}},"required":["ok","error"]}}}},"404":{"description":"valid input outside the dataset range","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":false},"error":{"type":"string","description":"machine-readable slug"},"message":{"type":"string","description":"human-readable explanation"}},"required":["ok","error"]}}}}}}},"/api/v1/range":{"get":{"summary":"Dataset range + last update","responses":{"200":{"description":"dataset metadata","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"data":{"type":"object","properties":{"first_ad":{"type":"string"},"first_bs":{"type":"string"},"last_ad":{"type":"string"},"last_bs":{"type":"string"},"total_entries":{"type":"integer"},"last_updated":{"type":"string"},"seed_hash":{"type":"string"}}}},"required":["ok","data"]}}}},"400":{"description":"invalid input (bad date shape, missing/duplicate params, unknown tz)","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":false},"error":{"type":"string","description":"machine-readable slug"},"message":{"type":"string","description":"human-readable explanation"}},"required":["ok","error"]}}}},"404":{"description":"valid input outside the dataset range","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":false},"error":{"type":"string","description":"machine-readable slug"},"message":{"type":"string","description":"human-readable explanation"}},"required":["ok","error"]}}}}}}},"/api/v1/month":{"get":{"summary":"All days of one calendar month (for calendar grids)","parameters":[{"name":"ad","in":"query","required":false,"schema":{"type":"string"},"description":"AD month, YYYY-MM"},{"name":"bs","in":"query","required":false,"schema":{"type":"string"},"description":"BS month, YYYY-MM. Provide exactly one of ad/bs."}],"responses":{"200":{"description":"day list","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"data":{"type":"object","properties":{"calendar":{"type":"string","enum":["ad","bs"]},"month":{"type":"string"},"name":{"type":"string"},"days":{"type":"array","items":{"type":"object","properties":{"id":{"type":"integer"},"ad":{"type":"string"},"bs":{"type":"string"},"day_of_week":{"type":"integer"}}}},"complete":{"type":"boolean","description":"false when the month is cut off by the dataset boundary"}}}},"required":["ok","data"]}}}},"400":{"description":"invalid input (bad date shape, missing/duplicate params, unknown tz)","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":false},"error":{"type":"string","description":"machine-readable slug"},"message":{"type":"string","description":"human-readable explanation"}},"required":["ok","error"]}}}},"404":{"description":"valid input outside the dataset range","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":false},"error":{"type":"string","description":"machine-readable slug"},"message":{"type":"string","description":"human-readable explanation"}},"required":["ok","error"]}}}}}}},"/api/v1/days-since":{"get":{"summary":"Days from a date to today (negative = future)","parameters":[{"name":"ad","in":"query","required":false,"schema":{"type":"string"},"description":"AD date. Lenient: YYYY-MM-DD, YYYYMMDD, YYYY_MM_DD, YYYY/MM/DD, with optional time portion (stripped), e.g. 2026-07-09T13:45:00"},{"name":"bs","in":"query","required":false,"schema":{"type":"string"},"description":"BS date. Provide exactly one of ad/bs."},{"name":"tz","in":"query","required":false,"schema":{"type":"string","default":"Asia/Kathmandu"}}],"responses":{"200":{"description":"signed day count","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"data":{"type":"object","properties":{"days":{"type":"integer"},"direction":{"type":"string","enum":["past","future","today"]},"from":{"type":"object","properties":{"id":{"type":"integer","description":"Stable row id (days since 1920-01-01, 1-based)"},"ad":{"type":"string","format":"date","description":"Gregorian date, YYYY-MM-DD"},"bs":{"type":"string","description":"Bikram Sambat date, YYYY-MM-DD"},"day":{"type":"string","description":"Weekday name (shared by both calendars)"},"day_of_week":{"type":"integer","minimum":0,"maximum":6,"description":"0=Sunday .. 6=Saturday"},"ad_human":{"type":"string","example":"Thursday, 9th July - 2026 AD"},"bs_human":{"type":"string","example":"Thursday, 25th Ashad - 2083 BS"},"ad_month_name":{"type":"string"},"bs_month_name":{"type":"string"},"divergence":{"type":"object","description":"Component-wise offset. AD + ad_to_bs = BS; bs_to_ad is its negation.","properties":{"ad_to_bs":{"type":"string","example":"+56y 8m 16d"},"bs_to_ad":{"type":"string","example":"-56y 8m 16d"}}}}},"today":{"type":"object","properties":{"id":{"type":"integer","description":"Stable row id (days since 1920-01-01, 1-based)"},"ad":{"type":"string","format":"date","description":"Gregorian date, YYYY-MM-DD"},"bs":{"type":"string","description":"Bikram Sambat date, YYYY-MM-DD"},"day":{"type":"string","description":"Weekday name (shared by both calendars)"},"day_of_week":{"type":"integer","minimum":0,"maximum":6,"description":"0=Sunday .. 6=Saturday"},"ad_human":{"type":"string","example":"Thursday, 9th July - 2026 AD"},"bs_human":{"type":"string","example":"Thursday, 25th Ashad - 2083 BS"},"ad_month_name":{"type":"string"},"bs_month_name":{"type":"string"},"divergence":{"type":"object","description":"Component-wise offset. AD + ad_to_bs = BS; bs_to_ad is its negation.","properties":{"ad_to_bs":{"type":"string","example":"+56y 8m 16d"},"bs_to_ad":{"type":"string","example":"-56y 8m 16d"}}}}}}}},"required":["ok","data"]}}}},"400":{"description":"invalid input (bad date shape, missing/duplicate params, unknown tz)","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":false},"error":{"type":"string","description":"machine-readable slug"},"message":{"type":"string","description":"human-readable explanation"}},"required":["ok","error"]}}}},"404":{"description":"valid input outside the dataset range","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":false},"error":{"type":"string","description":"machine-readable slug"},"message":{"type":"string","description":"human-readable explanation"}},"required":["ok","error"]}}}}}}},"/api/v1/days-between":{"get":{"summary":"Days between two dates (mixed calendars allowed)","parameters":[{"name":"from_ad","in":"query","required":false,"schema":{"type":"string"}},{"name":"from_bs","in":"query","required":false,"schema":{"type":"string"}},{"name":"to_ad","in":"query","required":false,"schema":{"type":"string"}},{"name":"to_bs","in":"query","required":false,"schema":{"type":"string"},"description":"Provide exactly one from_* and one to_*."}],"responses":{"200":{"description":"signed day count","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"data":{"type":"object","properties":{"days":{"type":"integer","description":"to - from (negative if to precedes from)"},"weeks":{"type":"integer"},"from":{"type":"object","properties":{"id":{"type":"integer","description":"Stable row id (days since 1920-01-01, 1-based)"},"ad":{"type":"string","format":"date","description":"Gregorian date, YYYY-MM-DD"},"bs":{"type":"string","description":"Bikram Sambat date, YYYY-MM-DD"},"day":{"type":"string","description":"Weekday name (shared by both calendars)"},"day_of_week":{"type":"integer","minimum":0,"maximum":6,"description":"0=Sunday .. 6=Saturday"},"ad_human":{"type":"string","example":"Thursday, 9th July - 2026 AD"},"bs_human":{"type":"string","example":"Thursday, 25th Ashad - 2083 BS"},"ad_month_name":{"type":"string"},"bs_month_name":{"type":"string"},"divergence":{"type":"object","description":"Component-wise offset. AD + ad_to_bs = BS; bs_to_ad is its negation.","properties":{"ad_to_bs":{"type":"string","example":"+56y 8m 16d"},"bs_to_ad":{"type":"string","example":"-56y 8m 16d"}}}}},"to":{"type":"object","properties":{"id":{"type":"integer","description":"Stable row id (days since 1920-01-01, 1-based)"},"ad":{"type":"string","format":"date","description":"Gregorian date, YYYY-MM-DD"},"bs":{"type":"string","description":"Bikram Sambat date, YYYY-MM-DD"},"day":{"type":"string","description":"Weekday name (shared by both calendars)"},"day_of_week":{"type":"integer","minimum":0,"maximum":6,"description":"0=Sunday .. 6=Saturday"},"ad_human":{"type":"string","example":"Thursday, 9th July - 2026 AD"},"bs_human":{"type":"string","example":"Thursday, 25th Ashad - 2083 BS"},"ad_month_name":{"type":"string"},"bs_month_name":{"type":"string"},"divergence":{"type":"object","description":"Component-wise offset. AD + ad_to_bs = BS; bs_to_ad is its negation.","properties":{"ad_to_bs":{"type":"string","example":"+56y 8m 16d"},"bs_to_ad":{"type":"string","example":"-56y 8m 16d"}}}}}}}},"required":["ok","data"]}}}},"400":{"description":"invalid input (bad date shape, missing/duplicate params, unknown tz)","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":false},"error":{"type":"string","description":"machine-readable slug"},"message":{"type":"string","description":"human-readable explanation"}},"required":["ok","error"]}}}},"404":{"description":"valid input outside the dataset range","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":false},"error":{"type":"string","description":"machine-readable slug"},"message":{"type":"string","description":"human-readable explanation"}},"required":["ok","error"]}}}}}}},"/api/v1/months/{bsYear}":{"get":{"summary":"BS month lengths for a year","parameters":[{"name":"bsYear","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"month table","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"data":{"type":"object","properties":{"bs_year":{"type":"integer"},"months":{"type":"array","items":{"type":"object","properties":{"month":{"type":"integer"},"name":{"type":"string"},"days":{"type":"integer"}}}},"total_days":{"type":"integer"},"complete":{"type":"boolean"}}}},"required":["ok","data"]}}}},"400":{"description":"invalid input (bad date shape, missing/duplicate params, unknown tz)","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":false},"error":{"type":"string","description":"machine-readable slug"},"message":{"type":"string","description":"human-readable explanation"}},"required":["ok","error"]}}}},"404":{"description":"valid input outside the dataset range","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":false},"error":{"type":"string","description":"machine-readable slug"},"message":{"type":"string","description":"human-readable explanation"}},"required":["ok","error"]}}}}}}},"/api/v1/dump":{"get":{"summary":"Full database dump (JSON attachment)","responses":{"200":{"description":"ad-bs-dump-v1 JSON: meta, bs_months, dates[[id, ad, bs], ...]"},"404":{"description":"no dump generated yet","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":false},"error":{"type":"string","description":"machine-readable slug"},"message":{"type":"string","description":"human-readable explanation"}},"required":["ok","error"]}}}}}}}}}