Skip to content

GET /hilal

Three endpoints for hilal visibility: the deciding evening is always the 29th of the current month, the night people actually go looking for the crescent. If the criteria are not fulfilled at any observation point, the month completes 30 days and the start shifts a day. Month boundaries come from the data publik yang dikeluarkan resmi oleh Kementerian Agama RI (publicly available official MABIMS tables) (not Umm al-Qura), and the astronomy uses a multi-site model: the criteria are evaluated at coastal observation points across Indonesia (currently 25 sites, from Sabang to Rote (see api/data/hilal_sites.json).

GET /api/v1/hilal/info?month={month}&year={year} → JSON
GET /api/v1/hilal/viz?month={month}&year={year} → PNG 720×1280
GET /api/v1/hilal/map?month={month}&year={year} → PNG 720×1280

info carries the numbers + verdict; viz renders a “where to look” sky chart; map renders the archipelago-wide visibility map. All are public but tightly rate limited (info 60/hour, viz and map 30/hour each per IP).

Parameter Type Required Description
month int 1–12 yes Target Hijri month (the chart shows its deciding evening)
year int yes Target Hijri year
retro true / false no (default false) Unlocks computed retro dates below the curated table (down to 1945-01-01), tagged mabims-retro. See data coverage for the reason why

Model: “seen anywhere in Indonesia”: the same Neo MABIMS criteria as the computed table, evaluated at each point’s own local sunset. When the criteria are met, the response reports the deciding site via deciding_site.

Terminal window
curl "https://api.mabims.dev/api/v1/hilal/info?month=11&year=1447"
{
"input": { "month": 11, "year": 1447 },
"month": { "name": "Dzulqa'dah", "number": 11, "year": 1447, "start": "2026-04-19" },
"previous_month": { "name": "Syawal", "number": 10, "year": 1447, "length": 29 },
"evening": {
"hijri_date": "29 Syawal 1447 H",
"hijri_day": 29,
"gregorian_date": "2026-04-18",
"sunset": "18:46",
"moonset": "19:31",
"moon_alt_deg": 10.36,
"moon_az_deg": 289.16,
"sun_alt_deg": -0.83,
"elongation_deg": 14.52,
"illumination_pct": 1.44,
"age_hours": 23.9,
"deciding_site": {
"name": "Sabang / Weh Island",
"lat": 5.8897,
"lon": 95.3164,
"elev_m": 16.0,
"tz": "Asia/Jakarta"
},
"sites_checked": 25,
"alt_ok": true,
"elong_ok": true,
"visible": true
},
"source": "mabims",
"warnings": []
}

visible is true when the criteria are met at at least one observation point:

  • Moon altitude ≥ 3.0°: topocentric (the hilal’s position relative to the observer), with atmospheric refraction applied (Bennett formula);
  • Elongation ≥ 6.4°: geocentric (the Indonesian hisab convention), the moon–sun angular separation;

(See the official MUI explainer and the government announcement via Setkab for the source of these criteria.)

both evaluated at that site’s local sunset on day 29. The further west a point sits, the higher the hilal stands at its sunset, so comfortable months are usually decided on the western coast (Aceh), while months with a southerly lunar declination can be decided along the southern arc (Java → Lesser Sunda). deciding_site is always present: when the criteria are met nowhere, the reported site is the best-margin one (closest to fulfilment), all altitude, elongation and time values refer to that site.

Sunset/moonset times, azimuths, illumination and lunar age are computed topocentrically at the deciding site (not Sabang), and times are displayed in the site’s own timezone (WIB/WITA).

A 720×1280 vertical PNG: sunset sky with the crescent (bright limb facing the sun), a verdict pill (MEMENUHI KRITERIA / TIDAK MEMENUHI / MENDEKATI BATAS / DI BAWAH HORIZON) and a PARAMETER · MABIMS MIN · STATUS criteria table plus a TITIK PENGAMAT row, the sky scene, criteria values and times all refer to the same deciding site. Output is deterministic per parameter.

Sample hilal visibility chart, 29 Syawal 1447 H, decided at Sabang

A 720×1280 PNG of the archipelago visibility region: the area where the Neo MABIMS criteria are met at local sunset, the altitude-3° and elongation-6.4° boundary lines, and 95 display points (green = meets the criteria, gray = does not). The deciding point from the 25-site model is marked with a yellow ring.

The card’s table uses the same deciding point as /hilal/viz, plus the TITIK MEMENUHI / TITIK TIDAK MEMENUHI counts from the 95 points, so both cards always name the same observer. Rate limit: 30/hour per IP.

Sample hilal visibility map, 29 Syawal 1447 H
  • Cache-Control: public, max-age=86400, s-maxage=86400: deterministic per parameter, publicly CDN-cached (CDN gets one render per edge location per day).
  • Rendering is CPU work: request only what you need and respect the rate limits.
  • Render cap: Hijri 1444–1475: PNG cards are only served in that range (see hilal_image_range on /meta); outside it the endpoint refuses with out_of_coverage. The date-conversion data cap remains coverage.forward_ceil.

Every response also carries an ETag. Send If-None-Match: <etag> and the server answers 304 Not Modified (empty body) when the data has not changed, with the same Cache-Control and ETag headers.

Code HTTP Cause
out_of_coverage 400 Month/year outside table coverage (see /meta)
computation_unavailable 503 Astronomy computation failed
render_failed 500 PNG rendering failed
invalid_retro 400 retro param is not a boolean value (accepts true/false, 1/0)
invalid_bare 400 bare is not a boolean value (accepts true/false, 1/0)
invalid_download 400 download is not a boolean value (accepts true/false, 1/0)
rate_limit_exceeded 429 Too many requests; wait per the Retry-After header (seconds)
not_found 404 Unknown path (uniform error envelope)

Boolean flags accept true/false (case-insensitive) and 1/0; absent = false.