{"openapi":"3.1.0","info":{"title":"Mahjong Scoring API","version":"1.0.0","description":"Riichi (Japanese) mahjong scoring as an API, computed locally and deterministically and exactly — the points a winning hand pays, straight from the scoring table, not a lookup you have to memorise. The score endpoint turns han and fu into the payment using base = fu × 2^(2 + han): a ron pays base × 4 (a dealer ron × 6) rounded up to the nearest 100, while a tsumo splits base × 2 from the dealer and base × 1 from each non-dealer (a dealer tsumo takes base × 2 from all three) — so a non-dealer 3 han 30 fu ron is 3,900, a 4 han 30 fu is 7,700, and a non-dealer mangan ron is 8,000. The limit endpoint classifies a hand: mangan (5 han, or 3–4 han where the fu pushes the base to 2,000), haneman (6–7), baiman (8–10), sanbaiman (11–12) and yakuman (13+), with the base points behind each. The honba endpoint adds the table bonuses — 300 per honba counter and 1,000 per riichi stick — on top of the won hand. Everything is computed locally and deterministically, so it is instant and exact. Ideal for mahjong apps, online-table and scorekeeper tools, club and tournament software, and learning aids. Pure local computation — no key, no third-party service, instant. Exact scoring-table maths. Live, nothing stored. 3 compute endpoints. Japanese riichi rules; other variants (MCR, Hong Kong) score differently.","contact":{"name":"PremiumApi","url":"https://www.oanor.com/by/premiumapi"}},"servers":[{"url":"https://api.oanor.com/mahjong-api","description":"oanor gateway"}],"tags":[{"name":"Mahjong"},{"name":"Meta"}],"components":{"securitySchemes":{"oanorKey":{"type":"apiKey","in":"header","name":"x-oanor-key","description":"Get your key at https://www.oanor.com/developer/keys"}}},"security":[{"oanorKey":[]}],"paths":{"/v1/honba":{"get":{"operationId":"get_v1_honba","tags":["Mahjong"],"summary":"Honba and riichi-stick bonuses","description":"","parameters":[{"name":"points","in":"query","required":true,"description":"Base won points","schema":{"type":"string"},"example":"3900"},{"name":"honba","in":"query","required":false,"description":"Honba counters","schema":{"type":"string"},"example":"2"},{"name":"riichi_sticks","in":"query","required":false,"description":"Riichi sticks on the table","schema":{"type":"string"},"example":"1"}],"security":[{"oanorKey":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"example":{"data":{"note":"Each honba counter adds 300 points to the win (100 from each player on a tsumo, all 300 from the discarder on a ron). Riichi sticks on the table are worth 1000 each and go to the winner. Sticks are picked up; honba carries to the next hand if the dealer keeps winning or on a draw.","inputs":{"honba":2,"points":3900,"riichi_sticks":1},"total_won":5500,"honba_bonus":600,"riichi_stick_bonus":1000},"meta":{"timestamp":"2026-06-06T15:30:46.268Z","request_id":"06faedde-9d94-4e20-a671-2cef6c3b3934"},"status":"ok","message":"Honba bonus","success":true}}}},"401":{"description":"Missing or invalid x-oanor-key header"},"402":{"description":"Active subscription required"},"429":{"description":"Rate-limit or monthly quota reached"},"502":{"description":"Upstream did not respond"}}}},"/v1/limit":{"get":{"operationId":"get_v1_limit","tags":["Mahjong"],"summary":"Limit-hand classification","description":"","parameters":[{"name":"han","in":"query","required":true,"description":"Han count","schema":{"type":"string"},"example":"7"},{"name":"fu","in":"query","required":false,"description":"Fu (default 30)","schema":{"type":"string"},"example":"30"}],"security":[{"oanorKey":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"example":{"data":{"note":"Limit hands cap the score: mangan (5 han, or 3–4 han with high fu where base reaches 2000) = 2000 base, haneman (6–7) = 3000, baiman (8–10) = 4000, sanbaiman (11–12) = 6000, yakuman (13+) = 8000. A non-dealer mangan ron is 8000 points; a dealer mangan ron is 12000.","limit":"haneman","inputs":{"fu":30,"han":7},"base_points":3000,"is_limit_hand":true},"meta":{"timestamp":"2026-06-06T15:30:46.376Z","request_id":"a37f5028-0e6b-4f45-b493-d10a5651cb6e"},"status":"ok","message":"Limit hand","success":true}}}},"401":{"description":"Missing or invalid x-oanor-key header"},"402":{"description":"Active subscription required"},"429":{"description":"Rate-limit or monthly quota reached"},"502":{"description":"Upstream did not respond"}}}},"/v1/score":{"get":{"operationId":"get_v1_score","tags":["Mahjong"],"summary":"Points from han and fu","description":"","parameters":[{"name":"han","in":"query","required":true,"description":"Han count","schema":{"type":"string"},"example":"3"},{"name":"fu","in":"query","required":false,"description":"Fu (default 30; ignored at 5+ han)","schema":{"type":"string"},"example":"30"},{"name":"dealer","in":"query","required":false,"description":"Dealer (oya) win","schema":{"type":"string"},"example":"false"},{"name":"tsumo","in":"query","required":false,"description":"Self-draw win","schema":{"type":"string"},"example":"false"}],"security":[{"oanorKey":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"example":{"data":{"note":"Riichi scoring: base = fu × 2^(2 + han); a ron pays base×4 (dealer ×6) rounded up to 100, a tsumo splits base×2 from the dealer and base×1 from each non-dealer (dealer tsumo is base×2 from all three). From 5 han the hand is a limit hand and fu no longer matters. Add honba and riichi sticks separately.","inputs":{"fu":30,"han":3,"tsumo":false,"dealer":false},"payments":{"discarder_pays":3900},"base_points":960,"total_points":3900},"meta":{"timestamp":"2026-06-06T15:30:46.479Z","request_id":"8f177790-cb6a-4120-8722-c6684cc70493"},"status":"ok","message":"Hand score","success":true}}}},"401":{"description":"Missing or invalid x-oanor-key header"},"402":{"description":"Active subscription required"},"429":{"description":"Rate-limit or monthly quota reached"},"502":{"description":"Upstream did not respond"}}}},"/v1/meta":{"get":{"operationId":"get_v1_meta","tags":["Meta"],"summary":"Spec","description":"","parameters":[],"security":[{"oanorKey":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"example":{"data":{"notes":"Exact riichi scoring: base = fu × 2^(2+han), ron base×4 (dealer ×6) round up to 100, tsumo split base×2/base×1. Limits mangan→yakuman. Japanese rules; for other variants (MCR, HK) the tables differ.","service":"mahjong-api","endpoints":{"GET /v1/meta":"This document.","GET /v1/honba":"Honba-counter and riichi-stick bonuses on top of a won hand.","GET /v1/limit":"Limit-hand classification (mangan … yakuman) from han and fu.","GET /v1/score":"Points a winning hand pays from han, fu, dealer status and win type."},"description":"Riichi (Japanese) mahjong scoring: points from han and fu, limit-hand classification, and honba/riichi-stick bonuses."},"meta":{"timestamp":"2026-06-06T15:30:46.577Z","request_id":"5a099961-8266-4597-9beb-93335fce5827"},"status":"ok","message":"Meta","success":true}}}},"401":{"description":"Missing or invalid x-oanor-key header"},"402":{"description":"Active subscription required"},"429":{"description":"Rate-limit or monthly quota reached"},"502":{"description":"Upstream did not respond"}}}}},"x-oanor-pricing":[{"slug":"free","name":"Free","price_cents_month":0,"monthly_call_quota":5000,"rps_limit":2,"hard_limit":true},{"slug":"starter","name":"Starter","price_cents_month":415,"monthly_call_quota":75000,"rps_limit":8,"hard_limit":true},{"slug":"pro","name":"Pro","price_cents_month":1290,"monthly_call_quota":310000,"rps_limit":20,"hard_limit":true},{"slug":"mega","name":"Mega","price_cents_month":3850,"monthly_call_quota":1450000,"rps_limit":48,"hard_limit":true}],"x-oanor-marketplace-url":"https://www.oanor.com/api/mahjong-api"}