Verses API
Purpose: Read verses by key, range, chapter, page, juz, hizb, or rub.
Use this when: You have a backend and need Quran text or metadata.
Do not use this when: You only have frontend or mobile code with no backend.
Backend required: Yes.
Allowed runtimes: Node.js, serverless functions, workers.
Required credentials: client_id, client_secret, Content API access.
Minimal import: @quranjs/api/server.
Use @quranjs/api/server.
import { createServerClient } from "@quranjs/api/server";
const client = createServerClient({
clientId: process.env.QF_CLIENT_ID!,
clientSecret: process.env.QF_CLIENT_SECRET!,
});
const verse = await client.content.v4.verses.byKey("2:255");
const chapterVerses = await client.content.v4.verses.byChapter("1");
const randomVerse = await client.content.v4.verses.random();
Tafsirs In Verse Lists
Pass tafsirs when a verse response should include tafsir snippets. Grouped tafsir resources now return populated text on v4 list endpoints such as byChapter, byPage, byJuz, byHizb, and byRub.
const verses = await client.content.v4.verses.byChapter("1", {
tafsirs: [169],
});
const firstTafsir = verses[0]?.tafsirs?.[0];
console.log(firstTafsir?.resourceId, firstTafsir?.text);
Word Audio Paths
Requesting word data can include word.audioUrl for each word. That value is a relative word-by-word asset path such as wbw/001_001_001.mp3, not a /content/api/v4/... endpoint.
const verse = await client.content.v4.verses.byKey("1:1", {
words: true,
wordFields: {
audio: true,
location: true,
},
});
const firstWord = verse.words?.[0];
const wordAudioUrl = firstWord?.audioUrl
? new URL(
firstWord.audioUrl.replace(/^\/+/, ""),
"https://audio.qurancdn.com/",
).toString()
: null;
Use word.audioUrl for single-word pronunciation playback. For chapter or ayah recitations, and for timing metadata, use the Audio API instead.
Common Mistake
Do not use the public SDK entrypoint for verse reads unless the platform auth model changes in the future.