openapi: 3.0.0 info: title: 'Pray API — Islamic Network' description: 'The Hijri devotional calendar: months, holy days, prayers (ṣalāts) and recitations (ṣalawāts, adhkārs, duʿās). Every response is wrapped in the `{code, status, data}` envelope shared across Islamic Network APIs; list endpoints add a `meta` sibling. Language keys are BCP 47 tags (`ar`, `en`, `ur`, …, and `ar-Latn` for transliteration); empty values are omitted entirely. Lists summarize, item endpoints expand.' contact: url: 'https://islamic.network' email: hello@islamic.network version: 1.0.0 servers: - url: 'https://pray.api.islamic.network/v1' description: Production paths: '/calendar/{month}': get: tags: - calendar summary: 'Month detail' description: "Description prose, the month's day records and the prayers recommended in it." operationId: getMonth parameters: - $ref: '#/components/parameters/month' responses: '200': description: 'The month, expanded.' content: application/json: schema: allOf: - { $ref: '#/components/schemas/Envelope' } - { properties: { data: { $ref: '#/components/schemas/MonthDetail' } }, type: object } '404': $ref: '#/components/responses/Error' '/calendar/{month}/{day}': get: tags: - calendar summary: 'Day detail — the flagship' description: 'The full day record: description, events, what-to-do, prayers with notes and times, and its ṣalawāts/adhkārs/duʿās in full. Day records are day-of-month anniversaries, not specific dates.' operationId: getDay parameters: - $ref: '#/components/parameters/month' - $ref: '#/components/parameters/day' responses: '200': description: 'The day, fully expanded.' content: application/json: schema: allOf: - { $ref: '#/components/schemas/Envelope' } - { properties: { data: { $ref: '#/components/schemas/DayDetail' } }, type: object } '404': $ref: '#/components/responses/Error' /calendar/today: get: tags: - calendar summary: 'Resolve a Gregorian date to its Hijri day record' description: 'Gregorian date → Hijri date (AlAdhan, HJCoSA calendar method) → day record (or null). Defaults to the server date (UTC).' operationId: getToday parameters: - name: date in: query description: 'Gregorian date as DD-MM-YYYY; defaults to today.' schema: type: string pattern: '^\d{2}-\d{2}-\d{4}$' example: 08-07-2026 responses: '200': description: 'The resolved date, its month, its day record (or null) and the next upcoming day record.' content: application/json: schema: allOf: - { $ref: '#/components/schemas/Envelope' } - { properties: { data: { $ref: '#/components/schemas/Today' } }, type: object } '400': $ref: '#/components/responses/Error' /days: get: tags: - calendar summary: 'All day records (summaries) in calendar order' description: 'For "upcoming holy days" features. Full records live at /calendar/{month}/{day}.' operationId: listDays parameters: - $ref: '#/components/parameters/page' - $ref: '#/components/parameters/limit' responses: '200': description: 'Paginated day summaries.' content: application/json: schema: allOf: - { $ref: '#/components/schemas/Envelope' } - { properties: { meta: { $ref: '#/components/schemas/Meta' }, data: { type: array, items: { $ref: '#/components/schemas/DaySummary' } } }, type: object } '/documentation/openapi/{format}': get: tags: - documentation summary: 'This specification, as OpenAPI 3' operationId: getOpenApiSpec parameters: - name: format in: path required: true schema: type: string enum: - yaml - json responses: '200': description: 'The OpenAPI document.' /months: get: tags: - calendar summary: 'All 12 Hijri months' operationId: listMonths responses: '200': description: 'Month summaries in calendar order; no pagination (12 fixed records).' content: application/json: schema: allOf: - { $ref: '#/components/schemas/Envelope' } - { properties: { data: { type: array, items: { $ref: '#/components/schemas/MonthSummary' } } }, type: object } '/{collection}': get: tags: - recitations summary: 'Recitation summaries' description: 'Lists summarize, items expand: summaries keep the Arabic formula so a list renders without item calls; translations, source and day links live on the item endpoint.' operationId: listRecitations parameters: - name: collection in: path required: true schema: type: string enum: - salawaats - adhkaars - duas - $ref: '#/components/parameters/page' - $ref: '#/components/parameters/limit' responses: '200': description: 'Paginated recitation summaries.' content: application/json: schema: allOf: - { $ref: '#/components/schemas/Envelope' } - { properties: { meta: { $ref: '#/components/schemas/Meta' }, data: { type: array, items: { $ref: '#/components/schemas/RecitationSummary' } } }, type: object } '/{collection}/{slug}': get: tags: - recitations summary: 'Full recitation entry' operationId: getRecitation parameters: - name: collection in: path required: true schema: type: string enum: - salawaats - adhkaars - duas - $ref: '#/components/parameters/slug' responses: '200': description: 'The entry: formula, translations, source, day links.' content: application/json: schema: allOf: - { $ref: '#/components/schemas/Envelope' } - { properties: { data: { $ref: '#/components/schemas/RecitationDetail' } }, type: object } '404': $ref: '#/components/responses/Error' /salaats: get: tags: - salaats summary: 'Prayer summaries' operationId: listSalaats parameters: - $ref: '#/components/parameters/page' - $ref: '#/components/parameters/limit' responses: '200': description: 'Paginated prayer summaries.' content: application/json: schema: allOf: - { $ref: '#/components/schemas/Envelope' } - { properties: { meta: { $ref: '#/components/schemas/Meta' }, data: { type: array, items: { $ref: '#/components/schemas/SalaatSummary' } } }, type: object } '/salaats/{slug}': get: tags: - salaats summary: 'Full prayer record' description: 'Description, method, and the months/days it is connected to with notes and times.' operationId: getSalaat parameters: - $ref: '#/components/parameters/slug' responses: '200': description: 'The prayer, expanded.' content: application/json: schema: allOf: - { $ref: '#/components/schemas/Envelope' } - { properties: { data: { $ref: '#/components/schemas/SalaatDetail' } }, type: object } '404': $ref: '#/components/responses/Error' /search: get: tags: - search summary: 'Diacritic-folded search across all collections' description: 'Matching is diacritic-folded (Ṣ→s, ā→a, ʿ/ʾ dropped, Arabic tashkīl stripped) across every language key of names, formulas, translations and prose — `tasbih`, `Tasbīḥ` and `تَسْبِيح` all match. Multiple query words AND together.' operationId: search parameters: - name: q in: query description: 'The query; at least 2 characters.' required: true schema: type: string example: tasbih minLength: 2 - name: type in: query description: 'Comma-separated collection filter.' schema: type: string example: 'salaats,adhkaars' - $ref: '#/components/parameters/page' - $ref: '#/components/parameters/limit' responses: '200': description: 'Matching records as typed summaries with the field paths that matched.' content: application/json: schema: allOf: - { $ref: '#/components/schemas/Envelope' } - { properties: { meta: { $ref: '#/components/schemas/Meta' }, data: { properties: { query: { type: string }, total: { type: integer }, results: { type: array, items: { $ref: '#/components/schemas/SearchResult' } } }, type: object } }, type: object } '400': $ref: '#/components/responses/Error' components: schemas: Name: description: 'Language-keyed name. Keys are BCP 47 tags; `ar-Latn` is the transliteration. Only non-empty languages appear.' type: object example: ar: 'صَلَاةُ التَّسْبِيح' ar-Latn: 'Ṣalāt al-Tasbīḥ' en: 'The Prayer of Glorification' additionalProperties: type: string Prose: description: 'Language-keyed prose. `raw` is the authored Markdown; `html` is rendered from it (Arabic-script runs wrapped in ``).' type: object additionalProperties: required: - raw - html properties: raw: description: "OpenAPI document root and shared components. Endpoint annotations live on\nthe v1 controllers; the assembled spec is served by\nGET /v1/documentation/openapi/{yaml|json}." type: string html: type: string type: object Highlights: description: 'Language-keyed list of short display highlights.' type: object example: en: - '300 Tasbīḥāt' - '4 Rakʿahs' - 'Voluntary — Nafl' additionalProperties: type: array items: type: string Translations: description: 'Renditions of a recitation formula, keyed by BCP 47 tag.' type: object additionalProperties: type: string Time: description: 'When a prayer is recommended; key icons off the stable `key`.' required: - key - label properties: key: type: string enum: - night - morning - duha - noon - afternoon - evening - last-third-of-the-night label: type: string example: Night type: object Event: required: - title properties: title: type: object additionalProperties: type: string url: description: 'Present when the event is a first-class record on the events API.' type: string type: object Meta: description: 'Pagination block, sibling of `data` on list endpoints.' required: - total - page - limit - pages properties: total: type: integer page: type: integer limit: type: integer pages: type: integer type: object Envelope: required: - code - status properties: code: type: integer example: 200 status: type: string example: OK type: object MonthSummary: required: - number - name - url properties: number: type: integer maximum: 12 minimum: 1 name: $ref: '#/components/schemas/Name' url: type: string type: object MonthRef: description: 'Minimal month reference embedded in summaries.' required: - number - name properties: number: type: integer name: $ref: '#/components/schemas/Name' type: object MonthDetail: allOf: - $ref: '#/components/schemas/MonthSummary' - properties: description: $ref: '#/components/schemas/Prose' days: type: array items: properties: number: { type: integer } slug: { type: string } name: { $ref: '#/components/schemas/Name' } url: { type: string } type: object salaats: description: 'Prayers recommended in this month.' type: array items: properties: id: { type: string } slug: { type: string } name: { $ref: '#/components/schemas/Name' } highlights: { $ref: '#/components/schemas/Highlights' } note: { type: string, example: 'First 10 days' } url: { type: string } type: object type: object DaySummary: required: - id - number - slug - month - name - url properties: id: type: string number: description: 'Day of the Hijri month.' type: integer slug: type: string example: muharram-10 month: $ref: '#/components/schemas/MonthRef' name: $ref: '#/components/schemas/Name' url: type: string type: object DayDetail: description: 'A day-of-month record (anniversary, not a specific date), fully expanded.' required: - id - slug - url - number - month - name - events - salaats - salawaats - adhkaars - duas properties: id: type: string slug: type: string url: type: string number: type: integer month: $ref: '#/components/schemas/MonthSummary' name: $ref: '#/components/schemas/Name' description: $ref: '#/components/schemas/Prose' events: type: array items: $ref: '#/components/schemas/Event' what_to_do: $ref: '#/components/schemas/Prose' salaats: type: array items: properties: id: type: string slug: type: string url: type: string name: $ref: '#/components/schemas/Name' highlights: $ref: '#/components/schemas/Highlights' note: type: string times: type: array items: $ref: '#/components/schemas/Time' type: object salawaats: type: array items: $ref: '#/components/schemas/RecitationEmbedded' adhkaars: type: array items: $ref: '#/components/schemas/RecitationEmbedded' duas: type: array items: $ref: '#/components/schemas/RecitationEmbedded' type: object Today: required: - date - month - day - next properties: date: properties: gregorian: type: string format: date example: '2026-07-08' hijri: properties: year: type: integer example: 1448 month: type: integer example: 1 day: type: integer example: 22 type: object type: object month: oneOf: - $ref: '#/components/schemas/MonthSummary' nullable: true day: oneOf: - $ref: '#/components/schemas/DayDetail' nullable: true description: 'The full day record, or null when today has none.' next: description: 'The next upcoming day record, wrapping across the year.' properties: number: type: integer slug: type: string month: $ref: '#/components/schemas/MonthRef' name: $ref: '#/components/schemas/Name' url: type: string type: object nullable: true type: object SalaatSummary: required: - id - slug - name - months - days - url properties: id: type: string slug: type: string example: salat-al-tasbih name: $ref: '#/components/schemas/Name' highlights: $ref: '#/components/schemas/Highlights' months: type: array items: $ref: '#/components/schemas/MonthRef' days: type: array items: properties: month: type: integer day: type: integer name: $ref: '#/components/schemas/Name' type: object url: type: string type: object SalaatDetail: required: - id - slug - url - name properties: id: type: string slug: type: string url: type: string name: $ref: '#/components/schemas/Name' highlights: $ref: '#/components/schemas/Highlights' description: $ref: '#/components/schemas/Prose' method: $ref: '#/components/schemas/Prose' source: type: string months: description: 'Months this prayer is connected to, with the junction note.' type: array items: properties: number: type: integer name: $ref: '#/components/schemas/Name' note: type: string url: type: string type: object days: description: 'Day records this prayer is connected to, with note and times.' type: array items: properties: month: type: integer day: type: integer slug: type: string name: $ref: '#/components/schemas/Name' note: type: string times: type: array items: $ref: '#/components/schemas/Time' url: type: string type: object type: object RecitationSummary: description: 'List entry: the formula stays so a list renders without item calls.' required: - id - slug - name - formula - url properties: id: type: string slug: type: string name: $ref: '#/components/schemas/Name' formula: description: 'The Arabic text itself — content, not a translation.' type: string url: type: string type: object RecitationEmbedded: description: 'Full entry as embedded in day details (no day links).' required: - id - slug - url - name - formula properties: id: type: string slug: type: string url: type: string name: $ref: '#/components/schemas/Name' formula: type: string translations: $ref: '#/components/schemas/Translations' source: type: string example: 'Fazilet Calendar' type: object RecitationDetail: allOf: - $ref: '#/components/schemas/RecitationEmbedded' - properties: days: description: 'Day records this entry is recited on.' type: array items: properties: month: { type: integer } day: { type: integer } slug: { type: string } name: { $ref: '#/components/schemas/Name' } url: { type: string } type: object type: object SearchResult: required: - type - matched_in - name - url properties: type: type: string enum: - month - day - salaat - salawaat - adhkaar - dua matched_in: description: 'Language-keyed field paths that matched, e.g. `name.ar-Latn`.' type: array items: type: string id: type: string number: description: 'Months only.' type: integer slug: type: string name: $ref: '#/components/schemas/Name' highlights: $ref: '#/components/schemas/Highlights' month: $ref: '#/components/schemas/MonthRef' url: type: string type: object responses: Error: description: 'Error — the envelope with a message string as `data`.' content: application/json: schema: required: - code - status - data properties: code: type: integer example: 404 status: type: string example: 'NOT FOUND' data: type: string example: 'No record for this day.' type: object parameters: page: name: page in: query description: 'Page number (default 1).' schema: type: integer default: 1 minimum: 1 limit: name: limit in: query description: 'Records per page (default 50, max 200).' schema: type: integer default: 50 maximum: 200 minimum: 1 month: name: month in: path description: 'Hijri month number.' required: true schema: type: integer maximum: 12 minimum: 1 day: name: day in: path description: 'Hijri day of month.' required: true schema: type: integer maximum: 30 minimum: 1 slug: name: slug in: path description: "The record's canonical URL key." required: true schema: type: string tags: - name: calendar description: 'Hijri months and day records' - name: salaats description: Prayers - name: recitations description: 'Ṣalawāts, adhkārs and duʿās' - name: search description: 'Diacritic-folded search' - name: documentation description: 'This specification'