Public prayer times API

Everything your clock knows about today's times, as JSON. Use it to build your own widget, feed a mobile app, print a monthly timetable, or drive a screen in software we haven't thought of.

There is no key and no sign-up. If you only want prayer times on your website, the embeddable widget does that for you without any code.

Note

The API returns exactly what your displays show — your iqamah offsets, your manual overrides, your calculation method, and your Jumu'ah setting. It is not a generic prayer-times calculator.

Before you start

The API answers for a clock only while its Public API switch is on (Dashboard → your clock → Embed). It starts off, and is separate from the website widget above it — turning one on doesn't turn the other on.

Note

The widget is on by default; the API isn't. A clock's address is its slug, and slugs are predictable — they come from the clock's name. Leaving the API closed by default keeps a clock that was never listed publicly from being findable by guesswork. Turn it on when you actually want to build against it.

You'll need your clock's slug — the last part of its display URL. It's shown under the clock name in the dashboard.

Today's times

GET https://salahclock.app/api/v1/clocks/{slug}
{
  "mosque": {
    "slug": "central-mosque",
    "name": "Central Mosque",
    "name_arabic": null,
    "address": "12 High Street",
    "timezone": "Europe/London",
    "latitude": 51.5074,
    "longitude": -0.1278,
    "calculation_method": "MuslimWorldLeague",
    "madhab": "Shafi",
    "primary_language": "en",
    "is_public": true,
    "profile_url": "/c/central-mosque",
    "synced_from": null
  },
  "today": {
    "date": "2026-09-06",
    "hijri": "14 Rabiʻ I 1448",
    "prayers": [
      {
        "key": "fajr",
        "name": "Fajr",
        "name_secondary": "الفجر",
        "adhan": "2026-09-06T04:12:00.000Z",
        "adhan_local": "05:12",
        "iqamah": "2026-09-06T04:32:00.000Z",
        "iqamah_local": "05:32",
        "is_overridden": false
      }
    ],
    "supplementary": [],
    "sunrise": "2026-09-06T05:23:00.000Z",
    "sunrise_local": "06:23",
    "sunset": "2026-09-06T18:41:00.000Z",
    "sunset_local": "19:41"
  },
  "tomorrow": { },
  "next": {
    "key": "asr",
    "name": "Asr",
    "adhan": "2026-09-06T14:30:00.000Z",
    "adhan_local": "15:30",
    "iqamah": "2026-09-06T14:45:00.000Z",
    "iqamah_local": "15:45",
    "seconds_until": 4231,
    "is_today": true
  },
  "announcement": null,
  "generated_at": "2026-09-06T13:19:29.000Z"
}

latitude and longitude are null unless the clock is listed on Discover. Embedding is on by default for every clock, including private ones in homes and offices — publishing prayer times is not the same as publishing a precise location for the building. Everything else, including the timezone the times are calculated for, is always present.

Every time appears twice on purpose:

  • adhan is the exact instant, ISO 8601 in UTC. Use this for arithmetic — countdowns, notifications, "is it Asr yet".
  • adhan_local is HH:MM in 24-hour form, already in the mosque's own timezone. Use this when you just want to print it.

Tip

next.seconds_until is correct at the moment the response was generated, and the response is cached for up to a minute. For a live countdown, count down from next.adhan rather than decrementing seconds_until.

A date range

GET https://salahclock.app/api/v1/clocks/{slug}/times?start=2026-10-01&days=31
ParameterMeaningDefault
startFirst day, YYYY-MM-DD, read in the mosque's timezone. Must be within a year of today.today
daysHow many days to return, 1–62.31

Returns mosque, start, days, and a timetable array of the same day objects as above. This is the endpoint for a printed monthly schedule.

Notes on the noon prayer

On Fridays, a clock set to replace Dhuhr with Jumu'ah returns jummah and not dhuhr; every other day it returns dhuhr and not jummah. You always get exactly the rows the mosque's own display is showing, so you never have to decide which one to hide.

Errors

Errors come back as JSON with the matching HTTP status.

{ "error": { "code": "api_disabled", "message": "This clock's owner has not enabled the public API for it." } }
StatuscodeMeaning
404not_foundNo clock with that slug.
403api_disabledThe owner has not turned on the Public API for this clock.
403unavailableThe clock is paused because the account is over its plan limit.
400invalid_daysdays wasn't a whole number between 1 and 62.
400invalid_startstart wasn't a valid date, or was more than a year away.
429rate_limitedToo many requests from your address. Wait a minute.

Using it from a browser

Both endpoints send Access-Control-Allow-Origin: *, so you can call them directly from JavaScript on any website — no proxy needed.

const res = await fetch("https://salahclock.app/api/v1/clocks/central-mosque");
const data = await res.json();
console.log(data.next.name, data.next.adhan_local);

Rate limits and caching

120 requests a minute per IP. Over that you get a 429 with a Retry-After header; wait a minute and carry on. That ceiling is far above any real use — it exists to stop scripts walking slugs, not to shape honest traffic.

Responses are cached for a minute (today) and fifteen minutes (date ranges), so polling faster than that only costs you latency. Cache what you fetch: prayer times for a given day don't change once the mosque has set them, and a monthly timetable is worth fetching once a month.

Asking an assistant instead

If you'd rather ask a question than write a request, SalahClock also speaks to Claude and ChatGPT directly — see Connect Claude or ChatGPT.