REST API Reference 接口參考
Base URL https://fengshuicalculator.com. No auth, no keys. All computations run on Beijing time (UTC+8). Every successful response wraps its payload in the provenance envelope described at the end of this page.
Machine-readable index: GET /v1 · MCP variant: /docs/mcp/
GET /v1/calendar?date=YYYY-MM-DD
Chinese calendar for one date: lunar date with leap month, zodiac, ganzhi pillars (Lichun convention, midnight day boundary), 建除 day officer, 黃道黑道 yellow/black path, 六曜 six-day cycle and Purple-White stars. Near-midnight dates carry a margin flag so historical almanac differences are visible, not silent.
$ curl "https://fengshuicalculator.com/v1/calendar?date=1985-02-20"
"data": {
"lunar": { "display": "农历1985正月初一", "is_leap_month": false },
"ganzhi": { "year": "乙丑", "day": "庚寅", "zodiac": "牛" },
"daily_almanac": { "jian_chu": "成", "huang_hei": "天刑", ... },
"near_midnight": false, "midnight_margin_minutes": 718.2
}
Golden value: 1985-02-20 is 农历正月初一 — the Chinese New Year crossover sample every calendar implementation gets wrong when it copies year numbers instead of computing new moons.
GET /v1/ganzhi?date=YYYY-MM-DD&hour=H
Four pillars (BaZi) under all four convention combinations: year by exact Lichun instant vs. by Lunar New Year; day boundary at midnight vs. at 23:00. Year/month pillars always follow the exact term instants — the four rows differ only where the traditions genuinely differ.
$ curl "https://fengshuicalculator.com/v1/ganzhi?date=1984-02-03&hour=12"
"pillars_by_convention": [
{ "year_convention": "lichun", "day_boundary": "midnight", "year": "癸亥", ... },
{ "year_convention": "lichun", "day_boundary": "at23", "year": "癸亥", ... },
{ "year_convention": "lunar_new_year", "day_boundary": "midnight", "year": "甲子", ... },
{ "year_convention": "lunar_new_year", "day_boundary": "at23", "year": "甲子", ... }
]
Golden value: 1984-02-03 sits between Spring Festival (02-02) and Lichun (02-04) — the one-day window where the two year conventions give 癸亥 vs 甲子. Every API that returns a single answer here is silently choosing a school; this one shows both.
GET /v1/solar-terms?year=YYYY
All 24 solar terms with exact Beijing instants (DE441-based astronomy, solved to <0.001″), apparent longitudes, ΔT values with source attribution, and a midnight margin for terms whose civil date could legitimately differ by one day.
$ curl "https://fengshuicalculator.com/v1/solar-terms?year=2026"
"terms": [ { "name": "立春", "beijing": "2026-02-04 04:02:05",
"apparent_longitude_deg": 315.0, "delta_t_seconds": 69.2, ... }, ... ]
GET /v1/kua?date=YYYY-MM-DD&hour=H&minute=M&gender=male|female&convention=standard|gen
Ming Gua (Kua number) from a birth date — the year boundary is the exact Lichun instant (computed astronomically and shown in the response), not the calendar year. Returns the Luoshu number, trigram, East/West group, five-yellow substitution flag, and the eight directions with their Great Year cycle stars (A/B cross-checked). convention picks the five-yellow rule: standard (male→Kun, female→Gen) or gen (both→Gen).
$ curl "https://fengshuicalculator.com/v1/kua?date=2024-02-03&gender=male"
"lichun_year": 2023, "kua_number": 4, "trigram": "巽", "group": "东四",
"year_boundary_note": "生日在 2024 年立春之前——命卦属上一个立春年 2023",
"palaces": [ { "palace": "坎", "star": "生气", "auspicious": true }, ... ]
Born 3 Feb 2024 (before Lichun at 16:27 Beijing) the Kua is 4; born two days later it is 3. Calendar-year calculators get every early-February birth wrong — the response shows the instant it used so you can check.
GET /v1/flying-star?sitting=&yun=&kind=
Xuan Kong flying star natal chart. sitting is a mountain index 0–23 (0=子, clockwise 15° each) or the Chinese mountain name (子癸丑艮寅甲卯乙辰巽巳丙午丁未坤申庚酉辛戌乾亥壬). yun 1–9; omit for the current period. kind: xiagua (standard, default) or tigua (substitution). Returns the nine palaces (mountain/facing/period stars), forward/backward flight flags, classical pattern labels (到山到向/上山下水/双星会坐/双星会向…), and an ASCII grid for quick inspection.
$ curl "https://fengshuicalculator.com/v1/flying-star?sitting=壬"
"yun": 9, "sitting": "壬", "facing": "丙", "patterns": ["双星会向"],
"palaces": [ { "palace": "中", "yun": 9, "shan": 5, "xiang": 4 }, ... ]
GET /v1/yun?date=YYYY-MM-DD
San Yuan period (三元九运) for a date — periods switch at Lichun, anchored 1984 = start of Period 7, 20 years each. Use it to derive yun from a construction year before calling /v1/flying-star.
$ curl "https://fengshuicalculator.com/v1/yun?date=2026-10-13" "yun": 9, "yun_chinese": "九", "yuan": "下元", "period_range": "2024–2043"
GET /v1/rulesets
The rule sets the kernel actually implements, with parameters and an honest review_state. Nothing unimplemented is advertised here — that's the point of the endpoint.
POST /v1/replay
The verification call: send the original kernel request (and optionally the expected digest + engine version) and get a recomputed digest plus a verdict — MATCH — byte-identical reproduction or an honest mismatch. Engine version mismatches return 409. See the fingerprint format for what the digest covers.
$ curl -X POST https://fengshuicalculator.com/v1/replay \
-H 'Content-Type: application/json' \
-d '{"request":{"beijing":[1985,2,20,12,0,0],"year_convention":"lichun","day_boundary":"midnight"}}'
"input_digest": "…64 hex…", "digest_match": null,
"verdict": "recomputed (no expected digest supplied)"
The envelope: provenance on every response
provenance.engine_version/provenance.ruleset_id/provenance.input_digest— the verification triple; digest is SHA-256 over the JCS-canonicalised request.disclaimer— cultural/educational computation, not predictions. Required on every endpoint, no exceptions.rules_not_implemented— spec'd-but-missing features, listed honestly per endpoint.- Errors are
{ "ok": false, "error": { "kind", "message" } }with meaningful HTTP codes (400 invalid input, 405 wrong method, 409 version mismatch, 422 kernel-refused). - CORS is open (
*) — browser demos welcome; the endpoints are read-only and credential-free by construction.
Authentication & fair use
- Free tier — no key. Every endpoint is public. A soft fair-use gate applies per client IP: roughly 60 requests burst, refilling at 1/second, per server instance. Exceeding it returns
429with aRetry-Afterheader; every response carriesX-RateLimit-LimitandX-RateLimit-Remaining. - Pro subscribers — your license key is your API key. Send it as
Authorization: Bearer <license key>(the same ES256 key issued at signup and shown in the Pro workbench — verified offline by signature, no database lookup). That raises the bucket to 600 burst / 10 per second. An invalid or expired key gets an explicit401, never a silent downgrade. - Honest limits. The gate is enforced per serverless instance, not globally — it stops abusive loops, it is not a metering system, and it is deliberately kept off the database so the free path stays zero-config and fast. If you need guaranteed throughput, that is exactly what the Pro tier is for.
- MCP clients (/v1/mcp) are rate limited identically and may send the same Bearer header.
$ curl -H "Authorization: Bearer <your Pro license key>" "https://fengshuicalculator.com/v1/ganzhi?date=2026-10-13&hour=12"
Conventions cheat-sheet
Year pillar flips at the exact Lichun instant (unless you call /v1/ganzhi for the alternatives) · month pillar always at the exact jie instant · day boundary midnight by default, 23:00 opt-in via /v1/ganzhi · everything Beijing time (UTC+8) · date range 1901–2199. Historical LMT caveats: surfaced per response, see the accuracy report.
Related
Docs home · MCP endpoint · Fingerprint format · School dispute register · Methodology