Skip to main content

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.