Crop an ayah as an image
You want a picture of one verse for a share card, a slide or an email — somewhere you do not control the fonts. Quran PNG is a live service: one GET, no key, and the letterforms are the printed muṣḥaf’s, not a font’s.
One tool, one edition
Quran PNG is a tool, not one of the eight blocks. It is built on the artwork Quran SVG Elements publishes, and it is the shortest path from a reference to a picture of it. Reach for it when the destination cannot lay out Arabic: Canva, Figma, Keynote, a PDF generator, a social card.
It serves one edition: the KFGQPC Madani muṣḥaf in the riwayah of Ḥafṣ. There is no parameter to choose another, so every ayah number in a URL here is Kufan numbering. If you already render pages with Quran Engine and want a crop without a network, skip to the offline alternative.
Make one request
curl -o kursi.png \ "https://png.quran.ws/api/v1/image/2/255.png?layout=fit&aspect=wide&width=1400"That is āyat al-Kursī, 1400 pixels wide, repacked into a 16:9 card, transparent background, as a PNG. The same URL is an
<img>source —Access-Control-Allow-Origin: *is set.<img src="https://png.quran.ws/api/v1/image/2/255.png?layout=fit&aspect=wide&width=1400" alt="Surah 2, ayah 255, from the printed Madani muṣḥaf" />Build the path
GET /api/v1/image/{surah}/{range}.{png|svg|pdf}surahis 1–114.rangeis one ayah (255), a closed range (255-257) or an open range to the end of the surah (1-). Ranges never cross a surah boundary, and a range past the end is rejected rather than clamped. The extension chooses the format; aformat=query parameter is only read when there is no extension, so/2/255.png?format=webpreturns a PNG.A query-string form exists for callers who would rather not build a path:
GET /api/v1/image?surah=112&from=1&to=4&format=svgChoose the layout and the look
Two layouts, because the artwork is only ever moved, never scaled.
mushaf(the default) keeps every word at its printed x, so the aspect ratio is whatever the printed lines give.fitrepacks the same artwork into justified lines filling an aspect you choose.Parameter Values Default Notes layoutmushaf·fitmushafaspectsquarepoststorywidebanner, orw:hsquarefitonly;2.5:1is accepted though/api/v1/optionslists only the five namesaligncenter·right·leftcenterfitonlyjustify0to switch offon fitonly; gaps move, letters never stretchwordSpacing0.3 – 4 1multiplier on the printed gap; fitonlylineSpacing0.6 – 3 1multiplier on the printed line height width64 – 8000 2000output pixels; PNG only — SVG and PDF are vector colorhex, #optional#231f20the ink backgroundhex transparent omit it and you get alpha padding0 – 400 24artwork units, not pixels basmalah0to omiton only affects a range starting at ayah 1 vany value unpinned changes caching only — see below A story card in this site’s colours, the whole of surah 112:
curl -o ikhlas.png "https://png.quran.ws/api/v1/image/112/1-.png?layout=fit&aspect=story&color=15705D&background=F8F5ED&padding=48&width=1080" # 200 image/png · x-quran-lines: 4 · x-quran-words: 15The service draws the basmalah for a range starting at ayah 1, as the plate does, and knows the two exceptions:
/9/1.pnghas none (surah 9 prints none — 9 words, 1 line), and in al-Fātiḥa it is ayah 1, so/1/1.png?basmalah=0still returns those 4 words.Read the layout back before you commit
Two headers tell you how the range laid out, so you can pick an aspect before you place the image:
x-quran-lines: 5 ← 2:255 under layout=fit&aspect=wide x-quran-words: 50The same verse is 6 lines under the plate (
layout=mushaf) and 4 lines ataspect=2.5:1. AHEADrequest carries the headers without the bytes.Check the status before you write the file
Every rejection is a
400withcontent-type: application/json— not an image:curl -s "https://png.quran.ws/api/v1/image/2/300.png" # {"error":"surah 2 has 286 ayahs, got 300-300"} curl -s "https://png.quran.ws/api/v1/image/2/255.png?width=9000" # {"error":"width must be between 64 and 8000, got 9000"}In code, the guard is one line, and skipping it produces a
.pngfile that is JSON inside and fails somewhere much later:const res = await fetch("https://png.quran.ws/api/v1/image/2/255.png?layout=fit&aspect=wide&width=1400"); if (!res.ok) throw new Error((await res.json()).error); // "surah 2 has 286 ayahs, got 300-300" const lines = Number(res.headers.get("x-quran-lines")); // 5 const blob = await res.blob(); // image/pngOver the per-IP rate limit you get
429with{"error":"too many requests, slow down"}; the deployed limit is not readable from outside, so throttle a bulk export and treat a429as expected.
Pinning, and what v actually does
Without v, the response revalidates: the edge serves cache-control: public, max-age=14400, stale-while-revalidate=604800.
With any v, it becomes public, max-age=31536000, immutable.
The parameter is documented as pinning a renderer version, and /api/v1/options says “pass v=3 to pin this
renderer”. The service treats v as present-or-absent: ?v=1 and ?v=9 both return today’s renderer,
x-render-version: 3. So a URL you froze in a printed document keeps serving the old bytes from caches while a
cold fetch after a renderer correction returns the new layout. Pin v when the image must
not change under you, and understand you have taken responsibility for re-pinning when x-render-version moves.
Without a server: Quran Engine
If your app already renders pages with Quran Engine, a crop is an engine call and needs no network. Run against page 001 on this site:
page.cropSvg("1:1", { pad: 2 });
// '<svg xmlns="http://www.w3.org/2000/svg" viewBox="111.62 216.07 122.23 28.98" width="122.23" height="28.98">…'
The result is a standalone SVG in the page’s current colours — the same artwork, from the same decomposition,
with no rate limit. It is the right choice inside a reader app; Quran PNG is the right choice when the caller is a
design tool or a curl.
What this is not for
| You want | Use |
|---|---|
| Warsh, Qālūn or any riwayah other than Ḥafṣ | Quran SVG — five muṣḥafs, and you crop the polygon yourself |
| The words as text, to search or store | Quran Text |
| A tappable page in a browser | Quran SVG Elements |
| A translation, a tafsīr, or a partial word | Not here — a range is drawn in full or refused |
Pick a surah, a range, a layout and an ink colour, and watch the URL and the live image change together.
How this works
The service holds no font. It loads the word and mark shapes that Quran SVG Elements publishes (the decomposition of
the KFGQPC Madani plates, keyed surah:ayah:word), and a render collects the shapes in your range and translates
them onto a new canvas; PNG is that SVG rasterised, PDF the same vector, page-sized. GET /api/v1/surahs reports the
edition: "hafs-kfgqpc", "KFGQPC Madani mushaf, V4 1441H", "render_version": 3.