diff --git a/docs/content_apis_versioned/4.0.0/chapter-reciter-audio-file.api.mdx b/docs/content_apis_versioned/4.0.0/chapter-reciter-audio-file.api.mdx index 02bb9ff7..d30194a5 100644 --- a/docs/content_apis_versioned/4.0.0/chapter-reciter-audio-file.api.mdx +++ b/docs/content_apis_versioned/4.0.0/chapter-reciter-audio-file.api.mdx @@ -5,7 +5,7 @@ description: "Get chapter's audio file of a reciter. Supports `segments` (boolea sidebar_label: "Get chapter's audio file of a reciter" hide_title: true hide_table_of_contents: true -api: {"tags":["Audio"],"description":"Get chapter's audio file of a reciter. Supports `segments` (boolean query param; default `false`). When `segments=true`, verse-level timestamp entries include `segments` ([word_index, start_ms, end_ms]). All time values are milliseconds.","operationId":"chapter-reciter-audio-file","parameters":[{"name":"reciter_id","in":"path","description":"Chapter-reciter ID from [/resources/chapter_reciters](/docs/content_apis_versioned/chapter-reciters). Do not use ayah-by-ayah recitation IDs from [/resources/recitations](/docs/content_apis_versioned/recitations) here.","required":true,"schema":{"type":"number"}},{"name":"chapter_number","in":"path","description":"The number of the chapter","required":true,"schema":{"maximum":114,"minimum":1,"type":"number"}},{"name":"segments","in":"query","required":false,"schema":{"type":"boolean","default":false},"description":"If true, each verse timestamp includes a `segments` array of [word_index, start_ms, end_ms] triplets. Time values are in milliseconds."}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"audio_file":{"type":"object","required":["id","chapter_id","file_size","format","audio_url"],"properties":{"id":{"type":"integer","example":457},"chapter_id":{"type":"integer","example":1},"file_size":{"type":"number","format":"float","description":"File size in bytes.","example":710784},"format":{"type":"string","example":"mp3"},"audio_url":{"type":"string","format":"uri","example":"https://download.quranicaudio.com/qdc/abu_bakr_shatri/murattal/1.mp3"},"timestamps":{"type":"array","description":"Present when timing data is available. If `segments=true`, each item may include a `segments` array.","items":{"type":"object","required":["verse_key","timestamp_from","timestamp_to","duration"],"properties":{"verse_key":{"type":"string","example":"1:1"},"timestamp_from":{"type":"integer","format":"int32","description":"Start offset in milliseconds from the beginning of the file.","example":0},"timestamp_to":{"type":"integer","format":"int32","description":"End offset in milliseconds from the beginning of the file.","example":6493},"duration":{"type":"integer","format":"int32","description":"Duration in milliseconds (mirrors source data; may be negative in legacy data).","example":-6493},"segments":{"type":"array","items":{"type":"array","minItems":3,"maxItems":3,"items":{"type":"integer","format":"int32"},"description":"[word_index, start_ms, end_ms] triplet. word_index is 1-based.","title":"SegmentTriplet"},"description":"Present only when `segments=true`. Word-level timing triplets for the verse.","nullable":true}},"title":"VerseTimestamp"}}},"title":"AudioFile"}},"required":["audio_file"],"title":"ChapterReciterAudioFileResponse"},"examples":{"default_no_segments":{"summary":"segments=false (default)","value":{"audio_file":{"id":457,"chapter_id":1,"file_size":710784,"format":"mp3","audio_url":"https://download.quranicaudio.com/qdc/abu_bakr_shatri/murattal/1.mp3"}}},"with_segments_true":{"summary":"segments=true (includes timestamps + segments)","value":{"audio_file":{"id":457,"chapter_id":1,"file_size":710784,"format":"mp3","audio_url":"https://download.quranicaudio.com/qdc/abu_bakr_shatri/murattal/1.mp3","timestamps":[{"verse_key":"1:1","timestamp_from":0,"timestamp_to":6493,"duration":-6493,"segments":[[1,0,630],[2,650,1570],[3,1570,3110],[4,3110,5590]]},{"verse_key":"1:2","timestamp_from":6493,"timestamp_to":11546,"duration":-5053,"segments":[[1,6493,7243],[2,7243,8123],[3,8143,8723],[4,8723,11193]]},{"verse_key":"1:3","timestamp_from":11546,"timestamp_to":15985,"duration":-4439,"segments":[[1,11546,12806],[2,12916,15366]]},{"verse_key":"1:4","timestamp_from":15985,"timestamp_to":21521,"duration":-5536,"segments":[[1,15985,16505],[2,16705,17235],[3,17265,19155]]},{"verse_key":"1:5","timestamp_from":21521,"timestamp_to":27835,"duration":-6314,"segments":[[1,21521,22591],[2,22591,23471],[3,23631,25001],[4,25001,27391]]},{"verse_key":"1:6","timestamp_from":27835,"timestamp_to":33388,"duration":-5553,"segments":[[1,27835,28265],[2,28265,29405],[3,29405,32545]]},{"verse_key":"1:7","timestamp_from":33388,"timestamp_to":53092,"duration":-19704,"segments":[[1,33388,34338],[2,34338,35448],[3,35518,36698],[4,36718,38678],[5,38678,39608],[6,39628,41638],[7,41638,43778],[8,43778,44218],[9,44338,51818]]}]}}}}}}},"400":{"description":"Will be returned when the request is invalid e.g. request is missing required headers or with invalid query parameters.","content":{"application/json":{"schema":{"title":"invalidRequestResponse","type":"object","properties":{"message":{"type":"string"},"type":{"type":"string","enum":["gateway_timeout","service_unavailable","bad_gateway","internal_server_error","unprocessable_entity","not_found","forbidden","unauthorized","invalid_request","invalid_token","insufficient_scope","service_error","invalid_path","rate_limit_exceeded"]},"success":{"type":"boolean"}}},"example":{"message":"The request is missing required headers or is invalid","type":"invalid_request","success":false}}}},"401":{"description":"Will be returned when the request is unauthorized.","content":{"application/json":{"schema":{"title":"unauthorizedResponse","type":"object","properties":{"message":{"type":"string"},"type":{"type":"string","enum":["gateway_timeout","service_unavailable","bad_gateway","internal_server_error","unprocessable_entity","not_found","forbidden","unauthorized","invalid_request","invalid_token","insufficient_scope","service_error","invalid_path","rate_limit_exceeded"]},"success":{"type":"boolean"}}},"example":{"message":"The request requires user authentication","type":"unauthorized","success":false}}}},"403":{"description":"Forbidden error. Can either be due to access token not being passed, having been expired or the caller trying to access a resource without enough permissions.","content":{"application/json":{"schema":{"title":"forbiddenResponse","type":"object","properties":{"message":{"type":"string"},"type":{"type":"string","enum":["gateway_timeout","service_unavailable","bad_gateway","internal_server_error","unprocessable_entity","not_found","forbidden","unauthorized","invalid_request","invalid_token","insufficient_scope","service_error","invalid_path","rate_limit_exceeded"]},"success":{"type":"boolean"}}},"example":{"message":"The server understood the request, but refuses to authorize it","type":"forbidden","success":false}}}},"404":{"description":"Not Found. The resource being accessed does not exist.","content":{"application/json":{"schema":{"title":"notFoundResponse","type":"object","properties":{"message":{"type":"string"},"type":{"type":"string","enum":["gateway_timeout","service_unavailable","bad_gateway","internal_server_error","unprocessable_entity","not_found","forbidden","unauthorized","invalid_request","invalid_token","insufficient_scope","service_error","invalid_path","rate_limit_exceeded"]},"success":{"type":"boolean"}}},"example":{"message":"The requested resource could not be found","type":"not_found","success":false}}}},"422":{"description":"Validation Error. The request includes one or more invalid params. Please check the request params and try again.","content":{"application/json":{"schema":{"title":"unprocessableEntityResponse","type":"object","properties":{"message":{"type":"string"},"type":{"type":"string","enum":["gateway_timeout","service_unavailable","bad_gateway","internal_server_error","unprocessable_entity","not_found","forbidden","unauthorized","invalid_request","invalid_token","insufficient_scope","service_error","invalid_path","rate_limit_exceeded"]},"success":{"type":"boolean"}}},"example":{"message":"The request was well-formed but was unable to be followed due to semantic errors","type":"unprocessable_entity","success":false}}}},"429":{"description":"Rate-limit exceeded","content":{"application/json":{"schema":{"title":"rateLimitExceededResponse","type":"object","properties":{"message":{"type":"string"},"type":{"type":"string","enum":["gateway_timeout","service_unavailable","bad_gateway","internal_server_error","unprocessable_entity","not_found","forbidden","unauthorized","invalid_request","invalid_token","insufficient_scope","service_error","invalid_path","rate_limit_exceeded"]},"success":{"type":"boolean"}}},"example":{"message":"Too many requests, please try again later","type":"rate_limit_exceeded","success":false}}}},"500":{"description":"Server Error. Something went wrong, try again later.","content":{"application/json":{"schema":{"title":"internalServerErrorResponse","type":"object","properties":{"message":{"type":"string"},"type":{"type":"string","enum":["gateway_timeout","service_unavailable","bad_gateway","internal_server_error","unprocessable_entity","not_found","forbidden","unauthorized","invalid_request","invalid_token","insufficient_scope","service_error","invalid_path","rate_limit_exceeded"]},"success":{"type":"boolean"}}},"example":{"message":"The server encountered an internal error and was unable to complete your request","type":"internal_server_error","success":false}}}},"502":{"description":"Bad Gateway","content":{"application/json":{"schema":{"title":"badGatewayResponse","type":"object","properties":{"message":{"type":"string"},"type":{"type":"string","enum":["gateway_timeout","service_unavailable","bad_gateway","internal_server_error","unprocessable_entity","not_found","forbidden","unauthorized","invalid_request","invalid_token","insufficient_scope","service_error","invalid_path","rate_limit_exceeded"]},"success":{"type":"boolean"}}},"example":{"message":"The server was acting as a gateway or proxy and received an invalid response from the upstream server","type":"bad_gateway","success":false}}}},"503":{"description":"Service Unavailable","content":{"application/json":{"schema":{"title":"serviceUnavailableResponse","type":"object","properties":{"message":{"type":"string"},"type":{"type":"string","enum":["gateway_timeout","service_unavailable","bad_gateway","internal_server_error","unprocessable_entity","not_found","forbidden","unauthorized","invalid_request","invalid_token","insufficient_scope","service_error","invalid_path","rate_limit_exceeded"]},"success":{"type":"boolean"}}},"example":{"message":"The server is currently unable to handle the request due to a temporary overload or scheduled maintenance","type":"service_unavailable","success":false}}}},"504":{"description":"Gateway Timeout","content":{"application/json":{"schema":{"title":"gatewayTimeoutResponse","type":"object","properties":{"message":{"type":"string"},"type":{"type":"string","enum":["gateway_timeout","service_unavailable","bad_gateway","internal_server_error","unprocessable_entity","not_found","forbidden","unauthorized","invalid_request","invalid_token","insufficient_scope","service_error","invalid_path","rate_limit_exceeded"]},"success":{"type":"boolean"}}},"example":{"message":"The server was acting as a gateway or proxy and did not receive a timely response from the upstream server","type":"gateway_timeout","success":false}}}}},"method":"get","path":"/chapter_recitations/{reciter_id}/{chapter_number}","servers":[{"url":"https://apis-prelive.quran.foundation/content/api/v4","description":"Pre-production Server"},{"url":"https://apis.quran.foundation/content/api/v4","description":"Production Server"}],"security":[{"x-auth-token":[],"x-client-id":[]}],"securitySchemes":{"x-auth-token":{"type":"apiKey","description":"The access token required for accessing the endpoints.","name":"x-auth-token","in":"header"},"x-client-id":{"type":"apiKey","description":"Your client Id","name":"x-client-id","in":"header"}},"info":{"title":"Content APIs","description":"Quran.Foundation Content APIs offer programmatic access to the Quran's core content like chapters, verses, recitations, translations, and more, distinct from user-specific data like notes and bookmarks provided by [User-related APIs](/docs/category/user-related-apis).\n\n:::important Integrity of Translations\nPlease **disable any automatic browser-translation features** (e.g. Google-Translate-in-Chrome) when displaying text returned by the *Translations* endpoints. \nRe-translating an already vetted Quranic translation can introduce serious semantic errors.\n:::\n\n ## How to get access \n\n We are using OAuth2 flows to authenticate and authorize requests. To get started, you need to [get an access token](/docs/tutorials/oidc/getting-started-with-oauth2#obtaining-oauth-20-client-credentials) to make requests to our APIs. Since the APIs are not user-related, you will need to use the `client_credentials` grant type and [`content` scope](/docs/user_related_apis_versioned/scopes#content) when sending a request to [The OAuth 2.0 Token Endpoint](/docs/oauth2_apis_versioned/oauth-2-token-exchange) to get the access token. \n\n```mermaid\nsequenceDiagram\n participant App as Your App\n participant Auth as Quran.Foundation
Authorization Server\n participant API as Quran.Foundation
Resources Server\n\n App->>Auth: Request Token with Client Credentials\n Auth-->>App: Token Response (access_token)\n App->>API: Use token to call API\n API-->>App: Requested resource\n\n Note over App,Auth: Access token expires (1 hour)\n\n App->>Auth: Re-issue access_token using client_credentials\n Auth-->>App: New access_token\n```\n\n After getting a valid access token, each request to get resources will have to include 2 headers mentioned below: `x-auth-token` and `x-client-id`. This spec also includes a small subset of Quran Reflect post-read endpoints that are compatible with the `client_credentials` grant. These operations still require `x-auth-token` and `x-client-id`, but they do not use the `content` scope. Use `post.read` for `/quran-reflect/v1/posts/feed`, `/quran-reflect/v1/posts/{id}`, and `/quran-reflect/v1/posts/user-posts/{id}`. Use `comment.read` for `/quran-reflect/v1/posts/{id}/comments` and `/quran-reflect/v1/posts/{id}/all-comments`. These are Quran Reflect gateway endpoints, not `/content/api/v4/...` endpoints.","version":"v4"},"postman":{"name":"Get chapter's audio file of a reciter","description":{"content":"Get chapter's audio file of a reciter. Supports `segments` (boolean query param; default `false`). When `segments=true`, verse-level timestamp entries include `segments` ([word_index, start_ms, end_ms]). All time values are milliseconds.","type":"text/plain"},"url":{"path":["chapter_recitations",":reciter_id",":chapter_number"],"host":["{{baseUrl}}"],"query":[{"disabled":false,"description":{"content":"If true, each verse timestamp includes a `segments` array of [word_index, start_ms, end_ms] triplets. Time values are in milliseconds.","type":"text/plain"},"key":"segments","value":""}],"variable":[{"disabled":false,"description":{"content":"(Required) Chapter-reciter ID from [/resources/chapter_reciters](/docs/content_apis_versioned/chapter-reciters). Do not use ayah-by-ayah recitation IDs from [/resources/recitations](/docs/content_apis_versioned/recitations) here.","type":"text/plain"},"type":"any","value":"","key":"reciter_id"},{"disabled":false,"description":{"content":"(Required) The number of the chapter","type":"text/plain"},"type":"any","value":"","key":"chapter_number"}]},"header":[{"key":"Accept","value":"application/json"}],"method":"GET"}} +api: {"tags":["Audio"],"description":"Get chapter's audio file of a reciter. Supports `segments` (boolean query param; default `false`). When `segments=true`, verse-level timestamp entries include `segments` ([word_index, start_ms, end_ms]). All time values are milliseconds.","operationId":"chapter-reciter-audio-file","parameters":[{"name":"reciter_id","in":"path","description":"Chapter-reciter ID from [/resources/chapter_reciters](/docs/content_apis_versioned/chapter-reciters). Do not use ayah-by-ayah recitation IDs from [/resources/recitations](/docs/content_apis_versioned/recitations) here.","required":true,"schema":{"type":"number"}},{"name":"chapter_number","in":"path","description":"The number of the chapter","required":true,"schema":{"maximum":114,"minimum":1,"type":"number"}},{"name":"segments","in":"query","required":false,"schema":{"type":"boolean","default":false},"description":"If true, each verse timestamp includes a `segments` array of [word_index, start_ms, end_ms] triplets. Time values are in milliseconds."}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"audio_file":{"type":"object","required":["id","chapter_id","file_size","format","audio_url"],"properties":{"id":{"type":"integer","example":457},"chapter_id":{"type":"integer","example":1},"file_size":{"type":"number","format":"float","description":"File size in bytes.","example":710784},"format":{"type":"string","example":"mp3"},"audio_url":{"type":"string","format":"uri","example":"https://download.quranicaudio.com/qdc/abu_bakr_shatri/murattal/1.mp3"},"duration":{"type":"integer","nullable":true,"description":"Length of the audio file in milliseconds. `null` when the length is unknown.","example":53000},"timestamps":{"type":"array","description":"Present when timing data is available. If `segments=true`, each item may include a `segments` array.","items":{"type":"object","required":["verse_key","timestamp_from","timestamp_to","duration"],"properties":{"verse_key":{"type":"string","example":"1:1"},"timestamp_from":{"type":"integer","format":"int32","description":"Start offset in milliseconds from the beginning of the file.","example":0},"timestamp_to":{"type":"integer","format":"int32","description":"End offset in milliseconds from the beginning of the file.","example":6493},"duration":{"type":"integer","format":"int32","description":"Duration in milliseconds (mirrors source data; may be negative in legacy data).","example":-6493},"segments":{"type":"array","items":{"type":"array","minItems":3,"maxItems":3,"items":{"type":"integer","format":"int32"},"description":"[word_index, start_ms, end_ms] triplet. word_index is 1-based.","title":"SegmentTriplet"},"description":"Present only when `segments=true`. Word-level timing triplets for the verse.","nullable":true}},"title":"VerseTimestamp"}}},"title":"AudioFile"}},"required":["audio_file"],"title":"ChapterReciterAudioFileResponse"},"examples":{"default_no_segments":{"summary":"segments=false (default)","value":{"audio_file":{"id":457,"chapter_id":1,"file_size":710784,"format":"mp3","audio_url":"https://download.quranicaudio.com/qdc/abu_bakr_shatri/murattal/1.mp3","duration":53000}}},"with_segments_true":{"summary":"segments=true (includes timestamps + segments)","value":{"audio_file":{"id":457,"chapter_id":1,"file_size":710784,"format":"mp3","audio_url":"https://download.quranicaudio.com/qdc/abu_bakr_shatri/murattal/1.mp3","duration":53000,"timestamps":[{"verse_key":"1:1","timestamp_from":0,"timestamp_to":6493,"duration":-6493,"segments":[[1,0,630],[2,650,1570],[3,1570,3110],[4,3110,5590]]},{"verse_key":"1:2","timestamp_from":6493,"timestamp_to":11546,"duration":-5053,"segments":[[1,6493,7243],[2,7243,8123],[3,8143,8723],[4,8723,11193]]},{"verse_key":"1:3","timestamp_from":11546,"timestamp_to":15985,"duration":-4439,"segments":[[1,11546,12806],[2,12916,15366]]},{"verse_key":"1:4","timestamp_from":15985,"timestamp_to":21521,"duration":-5536,"segments":[[1,15985,16505],[2,16705,17235],[3,17265,19155]]},{"verse_key":"1:5","timestamp_from":21521,"timestamp_to":27835,"duration":-6314,"segments":[[1,21521,22591],[2,22591,23471],[3,23631,25001],[4,25001,27391]]},{"verse_key":"1:6","timestamp_from":27835,"timestamp_to":33388,"duration":-5553,"segments":[[1,27835,28265],[2,28265,29405],[3,29405,32545]]},{"verse_key":"1:7","timestamp_from":33388,"timestamp_to":53092,"duration":-19704,"segments":[[1,33388,34338],[2,34338,35448],[3,35518,36698],[4,36718,38678],[5,38678,39608],[6,39628,41638],[7,41638,43778],[8,43778,44218],[9,44338,51818]]}]}}}}}}},"400":{"description":"Will be returned when the request is invalid e.g. request is missing required headers or with invalid query parameters.","content":{"application/json":{"schema":{"title":"invalidRequestResponse","type":"object","properties":{"message":{"type":"string"},"type":{"type":"string","enum":["gateway_timeout","service_unavailable","bad_gateway","internal_server_error","unprocessable_entity","not_found","forbidden","unauthorized","invalid_request","invalid_token","insufficient_scope","service_error","invalid_path","rate_limit_exceeded"]},"success":{"type":"boolean"}}},"example":{"message":"The request is missing required headers or is invalid","type":"invalid_request","success":false}}}},"401":{"description":"Will be returned when the request is unauthorized.","content":{"application/json":{"schema":{"title":"unauthorizedResponse","type":"object","properties":{"message":{"type":"string"},"type":{"type":"string","enum":["gateway_timeout","service_unavailable","bad_gateway","internal_server_error","unprocessable_entity","not_found","forbidden","unauthorized","invalid_request","invalid_token","insufficient_scope","service_error","invalid_path","rate_limit_exceeded"]},"success":{"type":"boolean"}}},"example":{"message":"The request requires user authentication","type":"unauthorized","success":false}}}},"403":{"description":"The request is forbidden, for example because a valid access token lacks the required scope or the client lacks permission.","content":{"application/json":{"schema":{"title":"forbiddenResponse","type":"object","properties":{"message":{"type":"string"},"type":{"type":"string","enum":["gateway_timeout","service_unavailable","bad_gateway","internal_server_error","unprocessable_entity","not_found","forbidden","unauthorized","invalid_request","invalid_token","insufficient_scope","service_error","invalid_path","rate_limit_exceeded"]},"success":{"type":"boolean"}}},"example":{"message":"The server understood the request, but refuses to authorize it","type":"forbidden","success":false}}}},"404":{"description":"Not Found. The resource being accessed does not exist.","content":{"application/json":{"schema":{"title":"notFoundResponse","type":"object","properties":{"message":{"type":"string"},"type":{"type":"string","enum":["gateway_timeout","service_unavailable","bad_gateway","internal_server_error","unprocessable_entity","not_found","forbidden","unauthorized","invalid_request","invalid_token","insufficient_scope","service_error","invalid_path","rate_limit_exceeded"]},"success":{"type":"boolean"}}},"example":{"message":"The requested resource could not be found","type":"not_found","success":false}}}},"422":{"description":"Validation Error. The request includes one or more invalid params. Please check the request params and try again.","content":{"application/json":{"schema":{"title":"unprocessableEntityResponse","type":"object","properties":{"message":{"type":"string"},"type":{"type":"string","enum":["gateway_timeout","service_unavailable","bad_gateway","internal_server_error","unprocessable_entity","not_found","forbidden","unauthorized","invalid_request","invalid_token","insufficient_scope","service_error","invalid_path","rate_limit_exceeded"]},"success":{"type":"boolean"}}},"example":{"message":"The request was well-formed but was unable to be followed due to semantic errors","type":"unprocessable_entity","success":false}}}},"429":{"description":"Rate-limit exceeded","content":{"application/json":{"schema":{"title":"rateLimitExceededResponse","type":"object","properties":{"message":{"type":"string"},"type":{"type":"string","enum":["gateway_timeout","service_unavailable","bad_gateway","internal_server_error","unprocessable_entity","not_found","forbidden","unauthorized","invalid_request","invalid_token","insufficient_scope","service_error","invalid_path","rate_limit_exceeded"]},"success":{"type":"boolean"}}},"example":{"message":"Too many requests, please try again later","type":"rate_limit_exceeded","success":false}}}},"500":{"description":"Server Error. Something went wrong, try again later.","content":{"application/json":{"schema":{"title":"internalServerErrorResponse","type":"object","properties":{"message":{"type":"string"},"type":{"type":"string","enum":["gateway_timeout","service_unavailable","bad_gateway","internal_server_error","unprocessable_entity","not_found","forbidden","unauthorized","invalid_request","invalid_token","insufficient_scope","service_error","invalid_path","rate_limit_exceeded"]},"success":{"type":"boolean"}}},"example":{"message":"The server encountered an internal error and was unable to complete your request","type":"internal_server_error","success":false}}}},"502":{"description":"Bad Gateway","content":{"application/json":{"schema":{"title":"badGatewayResponse","type":"object","properties":{"message":{"type":"string"},"type":{"type":"string","enum":["gateway_timeout","service_unavailable","bad_gateway","internal_server_error","unprocessable_entity","not_found","forbidden","unauthorized","invalid_request","invalid_token","insufficient_scope","service_error","invalid_path","rate_limit_exceeded"]},"success":{"type":"boolean"}}},"example":{"message":"The server was acting as a gateway or proxy and received an invalid response from the upstream server","type":"bad_gateway","success":false}}}},"503":{"description":"Service Unavailable","content":{"application/json":{"schema":{"title":"serviceUnavailableResponse","type":"object","properties":{"message":{"type":"string"},"type":{"type":"string","enum":["gateway_timeout","service_unavailable","bad_gateway","internal_server_error","unprocessable_entity","not_found","forbidden","unauthorized","invalid_request","invalid_token","insufficient_scope","service_error","invalid_path","rate_limit_exceeded"]},"success":{"type":"boolean"}}},"example":{"message":"The server is currently unable to handle the request due to a temporary overload or scheduled maintenance","type":"service_unavailable","success":false}}}},"504":{"description":"Gateway Timeout","content":{"application/json":{"schema":{"title":"gatewayTimeoutResponse","type":"object","properties":{"message":{"type":"string"},"type":{"type":"string","enum":["gateway_timeout","service_unavailable","bad_gateway","internal_server_error","unprocessable_entity","not_found","forbidden","unauthorized","invalid_request","invalid_token","insufficient_scope","service_error","invalid_path","rate_limit_exceeded"]},"success":{"type":"boolean"}}},"example":{"message":"The server was acting as a gateway or proxy and did not receive a timely response from the upstream server","type":"gateway_timeout","success":false}}}}},"x-qf-scopes":{"contractVersion":"content-scopes/v1","contractSha256":"0bba34fad8ac4ecc6d782eff14ae8f5cf50bac1784c832d5d1eb7d7f8be0ed36","contractStatus":"approved","routeId":"content.v4.chapter-reciter-audio-file","service":"content","anyOf":["content.read","content","content.audio.read"],"legacyAnyOf":["content.read","content"],"granularAnyOf":["content.audio.read"],"deprecatedForNewClients":["content.read","content"],"quotaBuckets":["content.read","content"],"rateLimitPolicyId":"preserve-existing-content-read-policy","responseBoundary":"endpoint-family-not-data-isolation","transport":{"note":"Both headers are required together. These are not OAuth2 bearer credentials.","headers":["x-auth-token","x-client-id"]}},"extensions":[{"key":"x-qf-scopes","value":{"contractVersion":"content-scopes/v1","contractSha256":"0bba34fad8ac4ecc6d782eff14ae8f5cf50bac1784c832d5d1eb7d7f8be0ed36","contractStatus":"approved","routeId":"content.v4.chapter-reciter-audio-file","service":"content","anyOf":["content.read","content","content.audio.read"],"legacyAnyOf":["content.read","content"],"granularAnyOf":["content.audio.read"],"deprecatedForNewClients":["content.read","content"],"quotaBuckets":["content.read","content"],"rateLimitPolicyId":"preserve-existing-content-read-policy","responseBoundary":"endpoint-family-not-data-isolation","transport":{"note":"Both headers are required together. These are not OAuth2 bearer credentials.","headers":["x-auth-token","x-client-id"]}}}],"method":"get","path":"/chapter_recitations/{reciter_id}/{chapter_number}","servers":[{"url":"https://apis-prelive.quran.foundation/content/api/v4","description":"Pre-production Server — testing and development only; Quran content is limited to Al-Fatihah (surah 1) and Al-Baqarah (surah 2)."},{"url":"https://apis.quran.foundation/content/api/v4","description":"Production Server"}],"security":[{"x-auth-token":[],"x-client-id":[]}],"securitySchemes":{"x-auth-token":{"type":"apiKey","description":"The access token required for accessing the endpoints.","name":"x-auth-token","in":"header"},"x-client-id":{"type":"apiKey","description":"Your client Id","name":"x-client-id","in":"header"}},"info":{"title":"Content APIs","description":"Quran Foundation Content APIs offer programmatic access to the Quran's core content like chapters, verses, recitations, translations, and more, distinct from user-specific data like notes and bookmarks provided by [User-related APIs](/docs/category/user-related-apis).\n\n:::note Prelive Content API limitation\nThe prelive environment is for testing and development only. Its Quran content dataset includes only Al-Fatihah (surah 1) and Al-Baqarah (surah 2). Test content requests using these surahs. For the complete Quran dataset, use the production environment after production access is approved.\n:::\n\n:::important Integrity of Translations\nPlease **disable any automatic browser-translation features** (e.g. Google-Translate-in-Chrome) when displaying text returned by the *Translations* endpoints. \nRe-translating an already vetted Quranic translation can introduce serious semantic errors.\n:::\n\n ## How to get access \n\n We are using OAuth2 flows to authenticate and authorize requests. To get started, you need to [get an access token](/docs/tutorials/oidc/getting-started-with-oauth2#obtaining-oauth-20-client-credentials) to make requests to our APIs. Since the APIs are not user-related, you will need to use the `client_credentials` grant type and [`content` scope](/docs/user_related_apis_versioned/scopes#content) when sending a request to [The OAuth 2.0 Token Endpoint](/docs/oauth2_apis_versioned/oauth-2-token-exchange) to get the access token. \n\n```mermaid\nsequenceDiagram\n participant App as Your App\n participant Auth as Quran Foundation
Authorization Server\n participant API as Quran Foundation
Resources Server\n\n App->>Auth: Request Token with Client Credentials\n Auth-->>App: Token Response (access_token)\n App->>API: Use token to call API\n API-->>App: Requested resource\n\n Note over App,Auth: Access token expires (1 hour)\n\n App->>Auth: Re-issue access_token using client_credentials\n Auth-->>App: New access_token\n```\n\n After getting a valid access token, each request to get resources will have to include 2 headers mentioned below: `x-auth-token` and `x-client-id`. This spec also includes a small subset of Quran Reflect post-read endpoints that are compatible with the `client_credentials` grant. These operations still require `x-auth-token` and `x-client-id`, but they do not use the `content` scope. Use `post.read` for `/quran-reflect/v1/posts/feed`, `/quran-reflect/v1/posts/{id}`, and `/quran-reflect/v1/posts/user-posts/{id}`. Use `comment.read` for `/quran-reflect/v1/posts/{id}/comments` and `/quran-reflect/v1/posts/{id}/all-comments`. These are Quran Reflect gateway endpoints, not `/content/api/v4/...` endpoints. The Qira'at endpoints under `/content/api/v4/qiraat/...` are scope-gated: they require the `qiraat.read` scope (or the parent `qiraat` scope) instead of `content`, so request the Qira'at scope your client has been approved for when you [get an access token](/docs/user_related_apis_versioned/scopes#qiraat).","version":"v4"},"postman":{"name":"Get chapter's audio file of a reciter","description":{"content":"Get chapter's audio file of a reciter. Supports `segments` (boolean query param; default `false`). When `segments=true`, verse-level timestamp entries include `segments` ([word_index, start_ms, end_ms]). All time values are milliseconds.","type":"text/plain"},"url":{"path":["chapter_recitations",":reciter_id",":chapter_number"],"host":["{{baseUrl}}"],"query":[{"disabled":false,"description":{"content":"If true, each verse timestamp includes a `segments` array of [word_index, start_ms, end_ms] triplets. Time values are in milliseconds.","type":"text/plain"},"key":"segments","value":""}],"variable":[{"disabled":false,"description":{"content":"(Required) Chapter-reciter ID from [/resources/chapter_reciters](/docs/content_apis_versioned/chapter-reciters). Do not use ayah-by-ayah recitation IDs from [/resources/recitations](/docs/content_apis_versioned/recitations) here.","type":"text/plain"},"type":"any","value":"","key":"reciter_id"},{"disabled":false,"description":{"content":"(Required) The number of the chapter","type":"text/plain"},"type":"any","value":"","key":"chapter_number"}]},"header":[{"key":"Accept","value":"application/json"}],"method":"GET"}} sidebar_class_name: "get api-method" info_path: docs/content_apis_versioned/4.0.0/content-apis custom_edit_url: null @@ -31,11 +31,11 @@ Get chapter's audio file of a reciter. Supports `segments` (boolean query param; Successful response -
Schema
    audio_file object required
    timestamps object[]
    +
    Schema
      audio_file object required
      timestamps object[]
      Present when timing data is available. If `segments=true`, each item may include a `segments` array. -
    • Array [
    • = 3`, `<= 3`"} schema={{"type":"array","items":{"type":"array","minItems":3,"maxItems":3,"items":{"type":"integer","format":"int32"},"description":"[word_index, start_ms, end_ms] triplet. word_index is 1-based.","title":"SegmentTriplet"},"description":"Present only when `segments=true`. Word-level timing triplets for the verse.","nullable":true}}>
    • ]

    segments=false (default)

    segments=true (includes timestamps + segments)

    +
  • Array [
  • = 3`, `<= 3`"} schema={{"type":"array","items":{"type":"array","minItems":3,"maxItems":3,"items":{"type":"integer","format":"int32"},"description":"[word_index, start_ms, end_ms] triplet. word_index is 1-based.","title":"SegmentTriplet"},"description":"Present only when `segments=true`. Word-level timing triplets for the verse.","nullable":true}}>
  • ]

segments=false (default)

segments=true (includes timestamps + segments)

Will be returned when the request is invalid e.g. request is missing required headers or with invalid query parameters. @@ -45,7 +45,7 @@ Will be returned when the request is unauthorized.
Schema
-Forbidden error. Can either be due to access token not being passed, having been expired or the caller trying to access a resource without enough permissions. +The request is forbidden, for example because a valid access token lacks the required scope or the client lacks permission.
Schema
diff --git a/docs/content_apis_versioned/4.0.0/chapter-reciter-audio-files.api.mdx b/docs/content_apis_versioned/4.0.0/chapter-reciter-audio-files.api.mdx index b1131c55..d41da6d6 100644 --- a/docs/content_apis_versioned/4.0.0/chapter-reciter-audio-files.api.mdx +++ b/docs/content_apis_versioned/4.0.0/chapter-reciter-audio-files.api.mdx @@ -5,7 +5,7 @@ description: "Get list of chapters' audio files of a reciter." sidebar_label: "List of all chapter audio files of a reciter" hide_title: true hide_table_of_contents: true -api: {"tags":["Audio"],"description":"Get list of chapters' audio files of a reciter.","operationId":"chapter-reciter-audio-files","parameters":[{"name":"reciter_id","in":"path","description":"Chapter-reciter ID from [/resources/chapter_reciters](/docs/content_apis_versioned/chapter-reciters). Do not use ayah-by-ayah recitation IDs from [/resources/recitations](/docs/content_apis_versioned/recitations) here.","required":true,"schema":{"type":"number"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"required":["audio_files"],"type":"object","properties":{"audio_files":{"type":"array","items":{"title":"Chapter Recitation","type":"object","properties":{"id":{"type":"integer","description":"The Id of the audio file"},"chapter_id":{"type":"integer","description":"The chapter id"},"file_size":{"type":"integer","description":"The file size in bytes"},"format":{"type":"string","description":"The format of the file"},"audio_url":{"type":"string","description":"The audio file's url"}},"example":{"id":1,"chapter_id":1,"file_size":710784,"format":"mp3","audio_url":"https://download.quranicaudio.com/quran/abdullaah_3awwaad_al-juhaynee//001.mp3"},"required":["id","chapter_id","file_size","format","audio_url"]}}}},"examples":{"default_success":{"summary":"Successful response","value":{"audio_files":[{"id":43,"chapter_id":22,"file_size":19779712,"format":"mp3","audio_url":"https://download.quranicaudio.com/quran/abdullaah_3awwaad_al-juhaynee//022.mp3"},{"id":87,"chapter_id":44,"file_size":6453376,"format":"mp3","audio_url":"https://download.quranicaudio.com/quran/abdullaah_3awwaad_al-juhaynee//044.mp3"}]}},"available_chapter_files":{"summary":"Chapter-level audio files for a reciter","value":{"audio_files":[{"id":43,"chapter_id":22,"file_size":19779712,"format":"mp3","audio_url":"https://download.quranicaudio.com/quran/abdullaah_3awwaad_al-juhaynee/022.mp3"},{"id":87,"chapter_id":44,"file_size":6453376,"format":"mp3","audio_url":"https://download.quranicaudio.com/quran/abdullaah_3awwaad_al-juhaynee/044.mp3"}]}}}}}},"400":{"description":"Will be returned when the request is invalid e.g. request is missing required headers or with invalid query parameters.","content":{"application/json":{"schema":{"title":"invalidRequestResponse","type":"object","properties":{"message":{"type":"string"},"type":{"type":"string","enum":["gateway_timeout","service_unavailable","bad_gateway","internal_server_error","unprocessable_entity","not_found","forbidden","unauthorized","invalid_request","invalid_token","insufficient_scope","service_error","invalid_path","rate_limit_exceeded"]},"success":{"type":"boolean"}}},"example":{"message":"The request is missing required headers or is invalid","type":"invalid_request","success":false}}}},"401":{"description":"Will be returned when the request is unauthorized.","content":{"application/json":{"schema":{"title":"unauthorizedResponse","type":"object","properties":{"message":{"type":"string"},"type":{"type":"string","enum":["gateway_timeout","service_unavailable","bad_gateway","internal_server_error","unprocessable_entity","not_found","forbidden","unauthorized","invalid_request","invalid_token","insufficient_scope","service_error","invalid_path","rate_limit_exceeded"]},"success":{"type":"boolean"}}},"example":{"message":"The request requires user authentication","type":"unauthorized","success":false}}}},"403":{"description":"Forbidden error. Can either be due to access token not being passed, having been expired or the caller trying to access a resource without enough permissions.","content":{"application/json":{"schema":{"title":"forbiddenResponse","type":"object","properties":{"message":{"type":"string"},"type":{"type":"string","enum":["gateway_timeout","service_unavailable","bad_gateway","internal_server_error","unprocessable_entity","not_found","forbidden","unauthorized","invalid_request","invalid_token","insufficient_scope","service_error","invalid_path","rate_limit_exceeded"]},"success":{"type":"boolean"}}},"example":{"message":"The server understood the request, but refuses to authorize it","type":"forbidden","success":false}}}},"404":{"description":"Not Found. The resource being accessed does not exist.","content":{"application/json":{"schema":{"title":"notFoundResponse","type":"object","properties":{"message":{"type":"string"},"type":{"type":"string","enum":["gateway_timeout","service_unavailable","bad_gateway","internal_server_error","unprocessable_entity","not_found","forbidden","unauthorized","invalid_request","invalid_token","insufficient_scope","service_error","invalid_path","rate_limit_exceeded"]},"success":{"type":"boolean"}}},"example":{"message":"The requested resource could not be found","type":"not_found","success":false}}}},"422":{"description":"Validation Error. The request includes one or more invalid params. Please check the request params and try again.","content":{"application/json":{"schema":{"title":"unprocessableEntityResponse","type":"object","properties":{"message":{"type":"string"},"type":{"type":"string","enum":["gateway_timeout","service_unavailable","bad_gateway","internal_server_error","unprocessable_entity","not_found","forbidden","unauthorized","invalid_request","invalid_token","insufficient_scope","service_error","invalid_path","rate_limit_exceeded"]},"success":{"type":"boolean"}}},"example":{"message":"The request was well-formed but was unable to be followed due to semantic errors","type":"unprocessable_entity","success":false}}}},"429":{"description":"Rate-limit exceeded","content":{"application/json":{"schema":{"title":"rateLimitExceededResponse","type":"object","properties":{"message":{"type":"string"},"type":{"type":"string","enum":["gateway_timeout","service_unavailable","bad_gateway","internal_server_error","unprocessable_entity","not_found","forbidden","unauthorized","invalid_request","invalid_token","insufficient_scope","service_error","invalid_path","rate_limit_exceeded"]},"success":{"type":"boolean"}}},"example":{"message":"Too many requests, please try again later","type":"rate_limit_exceeded","success":false}}}},"500":{"description":"Server Error. Something went wrong, try again later.","content":{"application/json":{"schema":{"title":"internalServerErrorResponse","type":"object","properties":{"message":{"type":"string"},"type":{"type":"string","enum":["gateway_timeout","service_unavailable","bad_gateway","internal_server_error","unprocessable_entity","not_found","forbidden","unauthorized","invalid_request","invalid_token","insufficient_scope","service_error","invalid_path","rate_limit_exceeded"]},"success":{"type":"boolean"}}},"example":{"message":"The server encountered an internal error and was unable to complete your request","type":"internal_server_error","success":false}}}},"502":{"description":"Bad Gateway","content":{"application/json":{"schema":{"title":"badGatewayResponse","type":"object","properties":{"message":{"type":"string"},"type":{"type":"string","enum":["gateway_timeout","service_unavailable","bad_gateway","internal_server_error","unprocessable_entity","not_found","forbidden","unauthorized","invalid_request","invalid_token","insufficient_scope","service_error","invalid_path","rate_limit_exceeded"]},"success":{"type":"boolean"}}},"example":{"message":"The server was acting as a gateway or proxy and received an invalid response from the upstream server","type":"bad_gateway","success":false}}}},"503":{"description":"Service Unavailable","content":{"application/json":{"schema":{"title":"serviceUnavailableResponse","type":"object","properties":{"message":{"type":"string"},"type":{"type":"string","enum":["gateway_timeout","service_unavailable","bad_gateway","internal_server_error","unprocessable_entity","not_found","forbidden","unauthorized","invalid_request","invalid_token","insufficient_scope","service_error","invalid_path","rate_limit_exceeded"]},"success":{"type":"boolean"}}},"example":{"message":"The server is currently unable to handle the request due to a temporary overload or scheduled maintenance","type":"service_unavailable","success":false}}}},"504":{"description":"Gateway Timeout","content":{"application/json":{"schema":{"title":"gatewayTimeoutResponse","type":"object","properties":{"message":{"type":"string"},"type":{"type":"string","enum":["gateway_timeout","service_unavailable","bad_gateway","internal_server_error","unprocessable_entity","not_found","forbidden","unauthorized","invalid_request","invalid_token","insufficient_scope","service_error","invalid_path","rate_limit_exceeded"]},"success":{"type":"boolean"}}},"example":{"message":"The server was acting as a gateway or proxy and did not receive a timely response from the upstream server","type":"gateway_timeout","success":false}}}}},"method":"get","path":"/chapter_recitations/{reciter_id}","servers":[{"url":"https://apis-prelive.quran.foundation/content/api/v4","description":"Pre-production Server"},{"url":"https://apis.quran.foundation/content/api/v4","description":"Production Server"}],"security":[{"x-auth-token":[],"x-client-id":[]}],"securitySchemes":{"x-auth-token":{"type":"apiKey","description":"The access token required for accessing the endpoints.","name":"x-auth-token","in":"header"},"x-client-id":{"type":"apiKey","description":"Your client Id","name":"x-client-id","in":"header"}},"info":{"title":"Content APIs","description":"Quran.Foundation Content APIs offer programmatic access to the Quran's core content like chapters, verses, recitations, translations, and more, distinct from user-specific data like notes and bookmarks provided by [User-related APIs](/docs/category/user-related-apis).\n\n:::important Integrity of Translations\nPlease **disable any automatic browser-translation features** (e.g. Google-Translate-in-Chrome) when displaying text returned by the *Translations* endpoints. \nRe-translating an already vetted Quranic translation can introduce serious semantic errors.\n:::\n\n ## How to get access \n\n We are using OAuth2 flows to authenticate and authorize requests. To get started, you need to [get an access token](/docs/tutorials/oidc/getting-started-with-oauth2#obtaining-oauth-20-client-credentials) to make requests to our APIs. Since the APIs are not user-related, you will need to use the `client_credentials` grant type and [`content` scope](/docs/user_related_apis_versioned/scopes#content) when sending a request to [The OAuth 2.0 Token Endpoint](/docs/oauth2_apis_versioned/oauth-2-token-exchange) to get the access token. \n\n```mermaid\nsequenceDiagram\n participant App as Your App\n participant Auth as Quran.Foundation
Authorization Server\n participant API as Quran.Foundation
Resources Server\n\n App->>Auth: Request Token with Client Credentials\n Auth-->>App: Token Response (access_token)\n App->>API: Use token to call API\n API-->>App: Requested resource\n\n Note over App,Auth: Access token expires (1 hour)\n\n App->>Auth: Re-issue access_token using client_credentials\n Auth-->>App: New access_token\n```\n\n After getting a valid access token, each request to get resources will have to include 2 headers mentioned below: `x-auth-token` and `x-client-id`. This spec also includes a small subset of Quran Reflect post-read endpoints that are compatible with the `client_credentials` grant. These operations still require `x-auth-token` and `x-client-id`, but they do not use the `content` scope. Use `post.read` for `/quran-reflect/v1/posts/feed`, `/quran-reflect/v1/posts/{id}`, and `/quran-reflect/v1/posts/user-posts/{id}`. Use `comment.read` for `/quran-reflect/v1/posts/{id}/comments` and `/quran-reflect/v1/posts/{id}/all-comments`. These are Quran Reflect gateway endpoints, not `/content/api/v4/...` endpoints.","version":"v4"},"postman":{"name":"List of all chapter audio files of a reciter","description":{"content":"Get list of chapters' audio files of a reciter.","type":"text/plain"},"url":{"path":["chapter_recitations",":reciter_id"],"host":["{{baseUrl}}"],"query":[],"variable":[{"disabled":false,"description":{"content":"(Required) Chapter-reciter ID from [/resources/chapter_reciters](/docs/content_apis_versioned/chapter-reciters). Do not use ayah-by-ayah recitation IDs from [/resources/recitations](/docs/content_apis_versioned/recitations) here.","type":"text/plain"},"type":"any","value":"","key":"reciter_id"}]},"header":[{"key":"Accept","value":"application/json"}],"method":"GET"}} +api: {"tags":["Audio"],"description":"Get list of chapters' audio files of a reciter.","operationId":"chapter-reciter-audio-files","parameters":[{"name":"reciter_id","in":"path","description":"Chapter-reciter ID from [/resources/chapter_reciters](/docs/content_apis_versioned/chapter-reciters). Do not use ayah-by-ayah recitation IDs from [/resources/recitations](/docs/content_apis_versioned/recitations) here.","required":true,"schema":{"type":"number"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"required":["audio_files"],"type":"object","properties":{"audio_files":{"type":"array","items":{"title":"Chapter Recitation","type":"object","properties":{"id":{"type":"integer","description":"The Id of the audio file"},"chapter_id":{"type":"integer","description":"The chapter id"},"file_size":{"type":"integer","description":"The file size in bytes"},"format":{"type":"string","description":"The format of the file"},"audio_url":{"type":"string","description":"The audio file's url"},"duration":{"type":"integer","nullable":true,"description":"Length of the audio file in milliseconds. `null` when the length is unknown."}},"example":{"id":1,"chapter_id":1,"file_size":710784,"format":"mp3","audio_url":"https://download.quranicaudio.com/quran/abdullaah_3awwaad_al-juhaynee//001.mp3"},"required":["id","chapter_id","file_size","format","audio_url"]}}}},"examples":{"default_success":{"summary":"Successful response","value":{"audio_files":[{"id":43,"chapter_id":22,"file_size":19779712,"format":"mp3","audio_url":"https://download.quranicaudio.com/quran/abdullaah_3awwaad_al-juhaynee//022.mp3"},{"id":87,"chapter_id":44,"file_size":6453376,"format":"mp3","audio_url":"https://download.quranicaudio.com/quran/abdullaah_3awwaad_al-juhaynee//044.mp3"}]}},"available_chapter_files":{"summary":"Chapter-level audio files for a reciter","value":{"audio_files":[{"id":43,"chapter_id":22,"file_size":19779712,"format":"mp3","audio_url":"https://download.quranicaudio.com/quran/abdullaah_3awwaad_al-juhaynee/022.mp3"},{"id":87,"chapter_id":44,"file_size":6453376,"format":"mp3","audio_url":"https://download.quranicaudio.com/quran/abdullaah_3awwaad_al-juhaynee/044.mp3"}]}}}}}},"400":{"description":"Will be returned when the request is invalid e.g. request is missing required headers or with invalid query parameters.","content":{"application/json":{"schema":{"title":"invalidRequestResponse","type":"object","properties":{"message":{"type":"string"},"type":{"type":"string","enum":["gateway_timeout","service_unavailable","bad_gateway","internal_server_error","unprocessable_entity","not_found","forbidden","unauthorized","invalid_request","invalid_token","insufficient_scope","service_error","invalid_path","rate_limit_exceeded"]},"success":{"type":"boolean"}}},"example":{"message":"The request is missing required headers or is invalid","type":"invalid_request","success":false}}}},"401":{"description":"Will be returned when the request is unauthorized.","content":{"application/json":{"schema":{"title":"unauthorizedResponse","type":"object","properties":{"message":{"type":"string"},"type":{"type":"string","enum":["gateway_timeout","service_unavailable","bad_gateway","internal_server_error","unprocessable_entity","not_found","forbidden","unauthorized","invalid_request","invalid_token","insufficient_scope","service_error","invalid_path","rate_limit_exceeded"]},"success":{"type":"boolean"}}},"example":{"message":"The request requires user authentication","type":"unauthorized","success":false}}}},"403":{"description":"The request is forbidden, for example because a valid access token lacks the required scope or the client lacks permission.","content":{"application/json":{"schema":{"title":"forbiddenResponse","type":"object","properties":{"message":{"type":"string"},"type":{"type":"string","enum":["gateway_timeout","service_unavailable","bad_gateway","internal_server_error","unprocessable_entity","not_found","forbidden","unauthorized","invalid_request","invalid_token","insufficient_scope","service_error","invalid_path","rate_limit_exceeded"]},"success":{"type":"boolean"}}},"example":{"message":"The server understood the request, but refuses to authorize it","type":"forbidden","success":false}}}},"404":{"description":"Not Found. The resource being accessed does not exist.","content":{"application/json":{"schema":{"title":"notFoundResponse","type":"object","properties":{"message":{"type":"string"},"type":{"type":"string","enum":["gateway_timeout","service_unavailable","bad_gateway","internal_server_error","unprocessable_entity","not_found","forbidden","unauthorized","invalid_request","invalid_token","insufficient_scope","service_error","invalid_path","rate_limit_exceeded"]},"success":{"type":"boolean"}}},"example":{"message":"The requested resource could not be found","type":"not_found","success":false}}}},"422":{"description":"Validation Error. The request includes one or more invalid params. Please check the request params and try again.","content":{"application/json":{"schema":{"title":"unprocessableEntityResponse","type":"object","properties":{"message":{"type":"string"},"type":{"type":"string","enum":["gateway_timeout","service_unavailable","bad_gateway","internal_server_error","unprocessable_entity","not_found","forbidden","unauthorized","invalid_request","invalid_token","insufficient_scope","service_error","invalid_path","rate_limit_exceeded"]},"success":{"type":"boolean"}}},"example":{"message":"The request was well-formed but was unable to be followed due to semantic errors","type":"unprocessable_entity","success":false}}}},"429":{"description":"Rate-limit exceeded","content":{"application/json":{"schema":{"title":"rateLimitExceededResponse","type":"object","properties":{"message":{"type":"string"},"type":{"type":"string","enum":["gateway_timeout","service_unavailable","bad_gateway","internal_server_error","unprocessable_entity","not_found","forbidden","unauthorized","invalid_request","invalid_token","insufficient_scope","service_error","invalid_path","rate_limit_exceeded"]},"success":{"type":"boolean"}}},"example":{"message":"Too many requests, please try again later","type":"rate_limit_exceeded","success":false}}}},"500":{"description":"Server Error. Something went wrong, try again later.","content":{"application/json":{"schema":{"title":"internalServerErrorResponse","type":"object","properties":{"message":{"type":"string"},"type":{"type":"string","enum":["gateway_timeout","service_unavailable","bad_gateway","internal_server_error","unprocessable_entity","not_found","forbidden","unauthorized","invalid_request","invalid_token","insufficient_scope","service_error","invalid_path","rate_limit_exceeded"]},"success":{"type":"boolean"}}},"example":{"message":"The server encountered an internal error and was unable to complete your request","type":"internal_server_error","success":false}}}},"502":{"description":"Bad Gateway","content":{"application/json":{"schema":{"title":"badGatewayResponse","type":"object","properties":{"message":{"type":"string"},"type":{"type":"string","enum":["gateway_timeout","service_unavailable","bad_gateway","internal_server_error","unprocessable_entity","not_found","forbidden","unauthorized","invalid_request","invalid_token","insufficient_scope","service_error","invalid_path","rate_limit_exceeded"]},"success":{"type":"boolean"}}},"example":{"message":"The server was acting as a gateway or proxy and received an invalid response from the upstream server","type":"bad_gateway","success":false}}}},"503":{"description":"Service Unavailable","content":{"application/json":{"schema":{"title":"serviceUnavailableResponse","type":"object","properties":{"message":{"type":"string"},"type":{"type":"string","enum":["gateway_timeout","service_unavailable","bad_gateway","internal_server_error","unprocessable_entity","not_found","forbidden","unauthorized","invalid_request","invalid_token","insufficient_scope","service_error","invalid_path","rate_limit_exceeded"]},"success":{"type":"boolean"}}},"example":{"message":"The server is currently unable to handle the request due to a temporary overload or scheduled maintenance","type":"service_unavailable","success":false}}}},"504":{"description":"Gateway Timeout","content":{"application/json":{"schema":{"title":"gatewayTimeoutResponse","type":"object","properties":{"message":{"type":"string"},"type":{"type":"string","enum":["gateway_timeout","service_unavailable","bad_gateway","internal_server_error","unprocessable_entity","not_found","forbidden","unauthorized","invalid_request","invalid_token","insufficient_scope","service_error","invalid_path","rate_limit_exceeded"]},"success":{"type":"boolean"}}},"example":{"message":"The server was acting as a gateway or proxy and did not receive a timely response from the upstream server","type":"gateway_timeout","success":false}}}}},"x-qf-scopes":{"contractVersion":"content-scopes/v1","contractSha256":"0bba34fad8ac4ecc6d782eff14ae8f5cf50bac1784c832d5d1eb7d7f8be0ed36","contractStatus":"approved","routeId":"content.v4.chapter-reciter-audio-files","service":"content","anyOf":["content.read","content","content.audio.read"],"legacyAnyOf":["content.read","content"],"granularAnyOf":["content.audio.read"],"deprecatedForNewClients":["content.read","content"],"quotaBuckets":["content.read","content"],"rateLimitPolicyId":"preserve-existing-content-read-policy","responseBoundary":"endpoint-family-not-data-isolation","transport":{"note":"Both headers are required together. These are not OAuth2 bearer credentials.","headers":["x-auth-token","x-client-id"]}},"extensions":[{"key":"x-qf-scopes","value":{"contractVersion":"content-scopes/v1","contractSha256":"0bba34fad8ac4ecc6d782eff14ae8f5cf50bac1784c832d5d1eb7d7f8be0ed36","contractStatus":"approved","routeId":"content.v4.chapter-reciter-audio-files","service":"content","anyOf":["content.read","content","content.audio.read"],"legacyAnyOf":["content.read","content"],"granularAnyOf":["content.audio.read"],"deprecatedForNewClients":["content.read","content"],"quotaBuckets":["content.read","content"],"rateLimitPolicyId":"preserve-existing-content-read-policy","responseBoundary":"endpoint-family-not-data-isolation","transport":{"note":"Both headers are required together. These are not OAuth2 bearer credentials.","headers":["x-auth-token","x-client-id"]}}}],"method":"get","path":"/chapter_recitations/{reciter_id}","servers":[{"url":"https://apis-prelive.quran.foundation/content/api/v4","description":"Pre-production Server — testing and development only; Quran content is limited to Al-Fatihah (surah 1) and Al-Baqarah (surah 2)."},{"url":"https://apis.quran.foundation/content/api/v4","description":"Production Server"}],"security":[{"x-auth-token":[],"x-client-id":[]}],"securitySchemes":{"x-auth-token":{"type":"apiKey","description":"The access token required for accessing the endpoints.","name":"x-auth-token","in":"header"},"x-client-id":{"type":"apiKey","description":"Your client Id","name":"x-client-id","in":"header"}},"info":{"title":"Content APIs","description":"Quran Foundation Content APIs offer programmatic access to the Quran's core content like chapters, verses, recitations, translations, and more, distinct from user-specific data like notes and bookmarks provided by [User-related APIs](/docs/category/user-related-apis).\n\n:::note Prelive Content API limitation\nThe prelive environment is for testing and development only. Its Quran content dataset includes only Al-Fatihah (surah 1) and Al-Baqarah (surah 2). Test content requests using these surahs. For the complete Quran dataset, use the production environment after production access is approved.\n:::\n\n:::important Integrity of Translations\nPlease **disable any automatic browser-translation features** (e.g. Google-Translate-in-Chrome) when displaying text returned by the *Translations* endpoints. \nRe-translating an already vetted Quranic translation can introduce serious semantic errors.\n:::\n\n ## How to get access \n\n We are using OAuth2 flows to authenticate and authorize requests. To get started, you need to [get an access token](/docs/tutorials/oidc/getting-started-with-oauth2#obtaining-oauth-20-client-credentials) to make requests to our APIs. Since the APIs are not user-related, you will need to use the `client_credentials` grant type and [`content` scope](/docs/user_related_apis_versioned/scopes#content) when sending a request to [The OAuth 2.0 Token Endpoint](/docs/oauth2_apis_versioned/oauth-2-token-exchange) to get the access token. \n\n```mermaid\nsequenceDiagram\n participant App as Your App\n participant Auth as Quran Foundation
Authorization Server\n participant API as Quran Foundation
Resources Server\n\n App->>Auth: Request Token with Client Credentials\n Auth-->>App: Token Response (access_token)\n App->>API: Use token to call API\n API-->>App: Requested resource\n\n Note over App,Auth: Access token expires (1 hour)\n\n App->>Auth: Re-issue access_token using client_credentials\n Auth-->>App: New access_token\n```\n\n After getting a valid access token, each request to get resources will have to include 2 headers mentioned below: `x-auth-token` and `x-client-id`. This spec also includes a small subset of Quran Reflect post-read endpoints that are compatible with the `client_credentials` grant. These operations still require `x-auth-token` and `x-client-id`, but they do not use the `content` scope. Use `post.read` for `/quran-reflect/v1/posts/feed`, `/quran-reflect/v1/posts/{id}`, and `/quran-reflect/v1/posts/user-posts/{id}`. Use `comment.read` for `/quran-reflect/v1/posts/{id}/comments` and `/quran-reflect/v1/posts/{id}/all-comments`. These are Quran Reflect gateway endpoints, not `/content/api/v4/...` endpoints. The Qira'at endpoints under `/content/api/v4/qiraat/...` are scope-gated: they require the `qiraat.read` scope (or the parent `qiraat` scope) instead of `content`, so request the Qira'at scope your client has been approved for when you [get an access token](/docs/user_related_apis_versioned/scopes#qiraat).","version":"v4"},"postman":{"name":"List of all chapter audio files of a reciter","description":{"content":"Get list of chapters' audio files of a reciter.","type":"text/plain"},"url":{"path":["chapter_recitations",":reciter_id"],"host":["{{baseUrl}}"],"query":[],"variable":[{"disabled":false,"description":{"content":"(Required) Chapter-reciter ID from [/resources/chapter_reciters](/docs/content_apis_versioned/chapter-reciters). Do not use ayah-by-ayah recitation IDs from [/resources/recitations](/docs/content_apis_versioned/recitations) here.","type":"text/plain"},"type":"any","value":"","key":"reciter_id"}]},"header":[{"key":"Accept","value":"application/json"}],"method":"GET"}} sidebar_class_name: "get api-method" info_path: docs/content_apis_versioned/4.0.0/content-apis custom_edit_url: null @@ -31,7 +31,7 @@ Get list of chapters' audio files of a reciter. Successful response -
Schema
    audio_files object[] required
  • Array [
  • ]

Successful response

Chapter-level audio files for a reciter

+
Schema
    audio_files object[] required
  • Array [
  • ]

Successful response

Chapter-level audio files for a reciter

Will be returned when the request is invalid e.g. request is missing required headers or with invalid query parameters. @@ -41,7 +41,7 @@ Will be returned when the request is unauthorized.
Schema
-Forbidden error. Can either be due to access token not being passed, having been expired or the caller trying to access a resource without enough permissions. +The request is forbidden, for example because a valid access token lacks the required scope or the client lacks permission.
Schema
diff --git a/docs/content_apis_versioned/4.0.0/chapter-reciters.api.mdx b/docs/content_apis_versioned/4.0.0/chapter-reciters.api.mdx index 961d3d87..478c446d 100644 --- a/docs/content_apis_versioned/4.0.0/chapter-reciters.api.mdx +++ b/docs/content_apis_versioned/4.0.0/chapter-reciters.api.mdx @@ -5,7 +5,7 @@ description: "Get list of available chapter reciters. Use these IDs with `/chapt sidebar_label: "List of Chapter Reciters" hide_title: true hide_table_of_contents: true -api: {"tags":["Audio"],"description":"Get list of available chapter reciters. Use these IDs with `/chapter_recitations/{reciter_id}`, `/chapter_recitations/{reciter_id}/{chapter_number}`, `/audio/reciters/{reciter_id}/timestamp`, and `/audio/reciters/{reciter_id}/lookup`. These IDs are not interchangeable with ayah-by-ayah recitation IDs from `/resources/recitations`.","operationId":"chapter-reciters","parameters":[{"name":"language","in":"query","description":"Name of reciters in specific language. Will fallback to English if we don't have names in specific language.","schema":{"type":"string","default":"en"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","required":["reciters"],"properties":{"reciters":{"type":"array","items":{"title":"Chapter Reciters","required":["id","name","style","qirat"],"type":"object","properties":{"id":{"type":"integer","description":"Reciter ID"},"name":{"type":"string","description":"Name of reciter in English"},"style":{"type":"object","properties":{"name":{"type":"string","nullable":true},"language_name":{"type":"string"}},"required":["language_name"]},"qirat":{"type":"object","properties":{"name":{"type":"string","nullable":true},"language_name":{"type":"string"}},"required":["language_name"]},"translated_name":{"nullable":true,"allOf":[{"title":"TranslatedName","required":["language_name","name"],"type":"object","properties":{"language_name":{"type":"string","default":"english"},"name":{"type":"string","description":"Name of the resource in specific language."}},"example":{"language_name":"english","name":"The Opener"}}]}},"example":{"id":3,"name":"Abu Bakr al-Shatri","style":{"name":"Murattal","language_name":"english"},"qirat":{"name":"Hafs","language_name":"english"},"translated_name":{"name":"Abu Bakr al-Shatri","language_name":"english"}}}}}},"examples":{"default_success":{"summary":"Successful response","value":{"reciters":[{"id":3,"name":"Abu Bakr al-Shatri","style":{"name":"Murattal","language_name":"english"},"qirat":{"name":"Hafs","language_name":"english"},"translated_name":{"name":"Abu Bakr al-Shatri","language_name":"english"}}]}}}}}},"400":{"description":"Will be returned when the request is invalid e.g. request is missing required headers or with invalid query parameters.","content":{"application/json":{"schema":{"title":"invalidRequestResponse","type":"object","properties":{"message":{"type":"string"},"type":{"type":"string","enum":["gateway_timeout","service_unavailable","bad_gateway","internal_server_error","unprocessable_entity","not_found","forbidden","unauthorized","invalid_request","invalid_token","insufficient_scope","service_error","invalid_path","rate_limit_exceeded"]},"success":{"type":"boolean"}}},"example":{"message":"The request is missing required headers or is invalid","type":"invalid_request","success":false}}}},"401":{"description":"Will be returned when the request is unauthorized.","content":{"application/json":{"schema":{"title":"unauthorizedResponse","type":"object","properties":{"message":{"type":"string"},"type":{"type":"string","enum":["gateway_timeout","service_unavailable","bad_gateway","internal_server_error","unprocessable_entity","not_found","forbidden","unauthorized","invalid_request","invalid_token","insufficient_scope","service_error","invalid_path","rate_limit_exceeded"]},"success":{"type":"boolean"}}},"example":{"message":"The request requires user authentication","type":"unauthorized","success":false}}}},"403":{"description":"Forbidden error. Can either be due to access token not being passed, having been expired or the caller trying to access a resource without enough permissions.","content":{"application/json":{"schema":{"title":"forbiddenResponse","type":"object","properties":{"message":{"type":"string"},"type":{"type":"string","enum":["gateway_timeout","service_unavailable","bad_gateway","internal_server_error","unprocessable_entity","not_found","forbidden","unauthorized","invalid_request","invalid_token","insufficient_scope","service_error","invalid_path","rate_limit_exceeded"]},"success":{"type":"boolean"}}},"example":{"message":"The server understood the request, but refuses to authorize it","type":"forbidden","success":false}}}},"404":{"description":"Not Found. The resource being accessed does not exist.","content":{"application/json":{"schema":{"title":"notFoundResponse","type":"object","properties":{"message":{"type":"string"},"type":{"type":"string","enum":["gateway_timeout","service_unavailable","bad_gateway","internal_server_error","unprocessable_entity","not_found","forbidden","unauthorized","invalid_request","invalid_token","insufficient_scope","service_error","invalid_path","rate_limit_exceeded"]},"success":{"type":"boolean"}}},"example":{"message":"The requested resource could not be found","type":"not_found","success":false}}}},"422":{"description":"Validation Error. The request includes one or more invalid params. Please check the request params and try again.","content":{"application/json":{"schema":{"title":"unprocessableEntityResponse","type":"object","properties":{"message":{"type":"string"},"type":{"type":"string","enum":["gateway_timeout","service_unavailable","bad_gateway","internal_server_error","unprocessable_entity","not_found","forbidden","unauthorized","invalid_request","invalid_token","insufficient_scope","service_error","invalid_path","rate_limit_exceeded"]},"success":{"type":"boolean"}}},"example":{"message":"The request was well-formed but was unable to be followed due to semantic errors","type":"unprocessable_entity","success":false}}}},"429":{"description":"Rate-limit exceeded","content":{"application/json":{"schema":{"title":"rateLimitExceededResponse","type":"object","properties":{"message":{"type":"string"},"type":{"type":"string","enum":["gateway_timeout","service_unavailable","bad_gateway","internal_server_error","unprocessable_entity","not_found","forbidden","unauthorized","invalid_request","invalid_token","insufficient_scope","service_error","invalid_path","rate_limit_exceeded"]},"success":{"type":"boolean"}}},"example":{"message":"Too many requests, please try again later","type":"rate_limit_exceeded","success":false}}}},"500":{"description":"Server Error. Something went wrong, try again later.","content":{"application/json":{"schema":{"title":"internalServerErrorResponse","type":"object","properties":{"message":{"type":"string"},"type":{"type":"string","enum":["gateway_timeout","service_unavailable","bad_gateway","internal_server_error","unprocessable_entity","not_found","forbidden","unauthorized","invalid_request","invalid_token","insufficient_scope","service_error","invalid_path","rate_limit_exceeded"]},"success":{"type":"boolean"}}},"example":{"message":"The server encountered an internal error and was unable to complete your request","type":"internal_server_error","success":false}}}},"502":{"description":"Bad Gateway","content":{"application/json":{"schema":{"title":"badGatewayResponse","type":"object","properties":{"message":{"type":"string"},"type":{"type":"string","enum":["gateway_timeout","service_unavailable","bad_gateway","internal_server_error","unprocessable_entity","not_found","forbidden","unauthorized","invalid_request","invalid_token","insufficient_scope","service_error","invalid_path","rate_limit_exceeded"]},"success":{"type":"boolean"}}},"example":{"message":"The server was acting as a gateway or proxy and received an invalid response from the upstream server","type":"bad_gateway","success":false}}}},"503":{"description":"Service Unavailable","content":{"application/json":{"schema":{"title":"serviceUnavailableResponse","type":"object","properties":{"message":{"type":"string"},"type":{"type":"string","enum":["gateway_timeout","service_unavailable","bad_gateway","internal_server_error","unprocessable_entity","not_found","forbidden","unauthorized","invalid_request","invalid_token","insufficient_scope","service_error","invalid_path","rate_limit_exceeded"]},"success":{"type":"boolean"}}},"example":{"message":"The server is currently unable to handle the request due to a temporary overload or scheduled maintenance","type":"service_unavailable","success":false}}}},"504":{"description":"Gateway Timeout","content":{"application/json":{"schema":{"title":"gatewayTimeoutResponse","type":"object","properties":{"message":{"type":"string"},"type":{"type":"string","enum":["gateway_timeout","service_unavailable","bad_gateway","internal_server_error","unprocessable_entity","not_found","forbidden","unauthorized","invalid_request","invalid_token","insufficient_scope","service_error","invalid_path","rate_limit_exceeded"]},"success":{"type":"boolean"}}},"example":{"message":"The server was acting as a gateway or proxy and did not receive a timely response from the upstream server","type":"gateway_timeout","success":false}}}}},"x-code-samples":[{"lang":"javascript","label":"Node.js","source":"// List of Chapter Reciters\nconst axios = require('axios');\n\nconst API_BASE_URL = 'https://apis.quran.foundation/content/api/v4';\nconst ACCESS_TOKEN = '';\nconst CLIENT_ID = '';\n\nasync function callApi(options = {}) {\n const response = await axios.get(\n `${API_BASE_URL}/resources/chapter_reciters`,\n {\n headers: {\n 'x-auth-token': ACCESS_TOKEN,\n 'x-client-id': CLIENT_ID\n },\n params: options\n }\n );\n return response.data;\n}\n\n// Example usage\ncallApi({\"language\":\"en\"})\n .then(data => console.log(data))\n .catch(err => console.error(err.response?.status, err.message));"},{"lang":"python","label":"Python","source":"# List of Chapter Reciters\nimport requests\n\nAPI_BASE_URL = 'https://apis.quran.foundation/content/api/v4'\nACCESS_TOKEN = ''\nCLIENT_ID = ''\n\ndef call_api(language=None):\n params = {k: v for k, v in {'language': language}.items() if v is not None}\n \n response = requests.get(\n f'{API_BASE_URL}/resources/chapter_reciters',\n headers={\n 'x-auth-token': ACCESS_TOKEN,\n 'x-client-id': CLIENT_ID\n },\n params=params\n )\n response.raise_for_status()\n return response.json()\n\n# Example usage\ntry:\n data = call_api(language=\"en\")\n print(data)\nexcept requests.HTTPError as e:\n print(f'Error {e.response.status_code}: {e}')"},{"lang":"go","label":"Go","source":"// List of Chapter Reciters\npackage main\n\nimport (\n \"fmt\"\n \"io\"\n \"net/http\"\n \"net/url\"\n)\n\nconst API_BASE_URL = \"https://apis.quran.foundation/content/api/v4\"\nconst ACCESS_TOKEN = \"\"\nconst CLIENT_ID = \"\"\n\nfunc callApi(params map[string]string) (string, error) {\n path := \"/resources/chapter_reciters\"\n endpoint := API_BASE_URL + path\n if params != nil && len(params) > 0 {\n values := url.Values{}\n for k, v := range params {\n values.Set(k, v)\n }\n endpoint = endpoint + \"?\" + values.Encode()\n }\n\n req, err := http.NewRequest(\"GET\", endpoint, nil)\n if err != nil {\n return \"\", err\n }\n req.Header.Set(\"x-auth-token\", ACCESS_TOKEN)\n req.Header.Set(\"x-client-id\", CLIENT_ID)\n\n resp, err := http.DefaultClient.Do(req)\n if err != nil {\n return \"\", err\n }\n defer resp.Body.Close()\n\n body, err := io.ReadAll(resp.Body)\n if err != nil {\n return \"\", err\n }\n return string(body), nil\n}\n\n// Example usage\nfunc main() {\n params := map[string]string{\"language\": \"en\"}\n data, err := callApi(params)\n if err != nil {\n fmt.Println(\"Error:\", err)\n return\n }\n fmt.Println(data)\n}"},{"lang":"ruby","label":"Ruby","source":"# List of Chapter Reciters\nrequire \"net/http\"\nrequire \"uri\"\n\nAPI_BASE_URL = \"https://apis.quran.foundation/content/api/v4\"\nACCESS_TOKEN = \"\"\nCLIENT_ID = \"\"\n\ndef call_api(params = {})\n path = \"/resources/chapter_reciters\"\n uri = URI(API_BASE_URL + path)\n uri.query = URI.encode_www_form(params) if params && !params.empty?\n request_class = Net::HTTP.const_get(\"Get\")\n request = request_class.new(uri)\n request[\"x-auth-token\"] = ACCESS_TOKEN\n request[\"x-client-id\"] = CLIENT_ID\n\n response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|\n http.request(request)\n end\n\n response.body\nend\n\n# Example usage\nparams = { \"language\" => \"en\" }\ndata = call_api(params)\nputs data"},{"lang":"csharp","label":"C#","source":"// List of Chapter Reciters\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Net.Http;\nusing System.Threading.Tasks;\n\nconst string API_BASE_URL = \"https://apis.quran.foundation/content/api/v4\";\nconst string ACCESS_TOKEN = \"\";\nconst string CLIENT_ID = \"\";\n\nstatic async Task CallApiAsync(Dictionary query = null)\n{\n var path = $@\"/resources/chapter_reciters\";\n var url = API_BASE_URL + path;\n if (query != null && query.Count > 0)\n {\n var queryString = string.Join(\"&\", query.Select(kvp =>\n $\"{Uri.EscapeDataString(kvp.Key)}={Uri.EscapeDataString(kvp.Value)}\"));\n url = $\"{url}?{queryString}\";\n }\n using var client = new HttpClient();\n using var request = new HttpRequestMessage(new HttpMethod(\"GET\"), url);\n request.Headers.Add(\"x-auth-token\", ACCESS_TOKEN);\n request.Headers.Add(\"x-client-id\", CLIENT_ID);\n\n using var response = await client.SendAsync(request);\n response.EnsureSuccessStatusCode();\n return await response.Content.ReadAsStringAsync();\n}\n\n// Example usage\nvar query = new Dictionary { {\"language\", \"en\"} };\nvar data = await CallApiAsync(query);\nConsole.WriteLine(data);"},{"lang":"php","label":"PHP","source":"# List of Chapter Reciters\n';\nconst CLIENT_ID = '';\n\nfunction callApi($params = []) {\n $path = \"/resources/chapter_reciters\";\n $url = API_BASE_URL . $path;\n if (!empty($params)) {\n $url .= '?' . http_build_query($params);\n }\n $ch = curl_init($url);\n curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);\n curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');\n curl_setopt($ch, CURLOPT_HTTPHEADER, [\n 'x-auth-token: ' . ACCESS_TOKEN,\n 'x-client-id: ' . CLIENT_ID\n ]);\n\n $response = curl_exec($ch);\n if ($response === false) {\n throw new Exception(curl_error($ch));\n }\n curl_close($ch);\n return $response;\n}\n\n// Example usage\n$params = ['language' => 'en'];\n$data = callApi($params);\necho $data;\n?>"},{"lang":"java","label":"Java","source":"// List of Chapter Reciters\nimport java.io.IOException;\nimport java.util.HashMap;\nimport java.util.Map;\nimport okhttp3.HttpUrl;\nimport okhttp3.OkHttpClient;\nimport okhttp3.Request;\nimport okhttp3.RequestBody;\nimport okhttp3.Response;\n\npublic class Main {\n private static final String API_BASE_URL = \"https://apis.quran.foundation/content/api/v4\";\n private static final String ACCESS_TOKEN = \"\";\n private static final String CLIENT_ID = \"\";\n\n public static String callApi(Map params) throws IOException {\n String path = \"/resources/chapter_reciters\";\n HttpUrl.Builder urlBuilder = HttpUrl.parse(API_BASE_URL + path).newBuilder();\n if (params != null) {\n for (Map.Entry entry : params.entrySet()) {\n urlBuilder.addQueryParameter(entry.getKey(), entry.getValue());\n }\n }\n String method = \"GET\";\n RequestBody requestBody = method.equals(\"GET\") ? null : RequestBody.create(new byte[0]);\n Request request = new Request.Builder()\n .url(urlBuilder.build())\n .addHeader(\"x-auth-token\", ACCESS_TOKEN)\n .addHeader(\"x-client-id\", CLIENT_ID)\n .method(method, requestBody)\n .build();\n\n OkHttpClient client = new OkHttpClient();\n Response response = client.newCall(request).execute();\n return response.body().string();\n }\n\n public static void main(String[] args) throws Exception {\n Map params = new HashMap<>();\n params.put(\"language\", \"en\");\n String data = callApi(params);\n System.out.println(data);\n }\n}"},{"lang":"powershell","label":"PowerShell","source":"# List of Chapter Reciters\n$API_BASE_URL = \"https://apis.quran.foundation/content/api/v4\"\n$ACCESS_TOKEN = \"\"\n$CLIENT_ID = \"\"\n\nfunction Call-Api([hashtable]$params = @{}) {\n $path = \"/resources/chapter_reciters\"\n $url = \"$API_BASE_URL$path\"\n if ($params.Count -gt 0) {\n $query = ($params.GetEnumerator() | ForEach-Object {\n \"$($_.Key)=$([System.Uri]::EscapeDataString([string]$_.Value))\"\n }) -join \"&\"\n $url = \"$url?$query\"\n }\n $headers = @{\n \"x-auth-token\" = $ACCESS_TOKEN\n \"x-client-id\" = $CLIENT_ID\n }\n\n Invoke-RestMethod -Method GET -Uri $url -Headers $headers\n}\n\n# Example usage\n$params = @{ language = \"en\" }\n$data = Call-Api($params)\nWrite-Output $data"},{"lang":"bash","label":"cURL","source":"# List of Chapter Reciters\ncurl -X GET \\\n 'https://apis.quran.foundation/content/api/v4/resources/chapter_reciters?language=en' \\\n -H 'x-auth-token: ' \\\n -H 'x-client-id: '"},{"lang":"text","label":"🤖 AI Prompt","source":"Implement a function to list of chapter reciters using the Quran Foundation API.\n\nEndpoint: GET /resources/chapter_reciters\nBase URL: https://apis.quran.foundation/content/api/v4\n\nRequired Headers (copy exactly):\n x-auth-token: \n x-client-id: \nOptional Query Parameters:\n language: Name of reciters in specific language. Will fallback to English if we don't have names in specific language.\n\nNotes:\n This endpoint returns chapter-reciter IDs.\n Use these IDs with `/chapter_recitations/{reciter_id}`, `/chapter_recitations/{reciter_id}/{chapter_number}`, `/audio/reciters/{reciter_id}/timestamp`, and `/audio/reciters/{reciter_id}/lookup`.\n These IDs are not interchangeable with ayah-by-ayah recitation IDs from `/resources/recitations`.\n\nImplementation Requirements:\n1. Build the request URL: {baseUrl}/resources/chapter_reciters?{queryParams}\n2. Inject both required headers on every request\n3. Handle errors safely:\n - 401: Token expired → re-request token and retry once\n - 403: Access denied → check client credentials\n - 429: Rate limited → implement exponential backoff\n\nAcceptance Checklist:\n- [ ] Function accepts optional parameters\n- [ ] Headers x-auth-token and x-client-id are sent\n- [ ] 401/403/429 errors are handled gracefully"}],"extensions":[{"key":"x-code-samples","value":[{"lang":"javascript","label":"Node.js","source":"// List of Chapter Reciters\nconst axios = require('axios');\n\nconst API_BASE_URL = 'https://apis.quran.foundation/content/api/v4';\nconst ACCESS_TOKEN = '';\nconst CLIENT_ID = '';\n\nasync function callApi(options = {}) {\n const response = await axios.get(\n `${API_BASE_URL}/resources/chapter_reciters`,\n {\n headers: {\n 'x-auth-token': ACCESS_TOKEN,\n 'x-client-id': CLIENT_ID\n },\n params: options\n }\n );\n return response.data;\n}\n\n// Example usage\ncallApi({\"language\":\"en\"})\n .then(data => console.log(data))\n .catch(err => console.error(err.response?.status, err.message));"},{"lang":"python","label":"Python","source":"# List of Chapter Reciters\nimport requests\n\nAPI_BASE_URL = 'https://apis.quran.foundation/content/api/v4'\nACCESS_TOKEN = ''\nCLIENT_ID = ''\n\ndef call_api(language=None):\n params = {k: v for k, v in {'language': language}.items() if v is not None}\n \n response = requests.get(\n f'{API_BASE_URL}/resources/chapter_reciters',\n headers={\n 'x-auth-token': ACCESS_TOKEN,\n 'x-client-id': CLIENT_ID\n },\n params=params\n )\n response.raise_for_status()\n return response.json()\n\n# Example usage\ntry:\n data = call_api(language=\"en\")\n print(data)\nexcept requests.HTTPError as e:\n print(f'Error {e.response.status_code}: {e}')"},{"lang":"go","label":"Go","source":"// List of Chapter Reciters\npackage main\n\nimport (\n \"fmt\"\n \"io\"\n \"net/http\"\n \"net/url\"\n)\n\nconst API_BASE_URL = \"https://apis.quran.foundation/content/api/v4\"\nconst ACCESS_TOKEN = \"\"\nconst CLIENT_ID = \"\"\n\nfunc callApi(params map[string]string) (string, error) {\n path := \"/resources/chapter_reciters\"\n endpoint := API_BASE_URL + path\n if params != nil && len(params) > 0 {\n values := url.Values{}\n for k, v := range params {\n values.Set(k, v)\n }\n endpoint = endpoint + \"?\" + values.Encode()\n }\n\n req, err := http.NewRequest(\"GET\", endpoint, nil)\n if err != nil {\n return \"\", err\n }\n req.Header.Set(\"x-auth-token\", ACCESS_TOKEN)\n req.Header.Set(\"x-client-id\", CLIENT_ID)\n\n resp, err := http.DefaultClient.Do(req)\n if err != nil {\n return \"\", err\n }\n defer resp.Body.Close()\n\n body, err := io.ReadAll(resp.Body)\n if err != nil {\n return \"\", err\n }\n return string(body), nil\n}\n\n// Example usage\nfunc main() {\n params := map[string]string{\"language\": \"en\"}\n data, err := callApi(params)\n if err != nil {\n fmt.Println(\"Error:\", err)\n return\n }\n fmt.Println(data)\n}"},{"lang":"ruby","label":"Ruby","source":"# List of Chapter Reciters\nrequire \"net/http\"\nrequire \"uri\"\n\nAPI_BASE_URL = \"https://apis.quran.foundation/content/api/v4\"\nACCESS_TOKEN = \"\"\nCLIENT_ID = \"\"\n\ndef call_api(params = {})\n path = \"/resources/chapter_reciters\"\n uri = URI(API_BASE_URL + path)\n uri.query = URI.encode_www_form(params) if params && !params.empty?\n request_class = Net::HTTP.const_get(\"Get\")\n request = request_class.new(uri)\n request[\"x-auth-token\"] = ACCESS_TOKEN\n request[\"x-client-id\"] = CLIENT_ID\n\n response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|\n http.request(request)\n end\n\n response.body\nend\n\n# Example usage\nparams = { \"language\" => \"en\" }\ndata = call_api(params)\nputs data"},{"lang":"csharp","label":"C#","source":"// List of Chapter Reciters\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Net.Http;\nusing System.Threading.Tasks;\n\nconst string API_BASE_URL = \"https://apis.quran.foundation/content/api/v4\";\nconst string ACCESS_TOKEN = \"\";\nconst string CLIENT_ID = \"\";\n\nstatic async Task CallApiAsync(Dictionary query = null)\n{\n var path = $@\"/resources/chapter_reciters\";\n var url = API_BASE_URL + path;\n if (query != null && query.Count > 0)\n {\n var queryString = string.Join(\"&\", query.Select(kvp =>\n $\"{Uri.EscapeDataString(kvp.Key)}={Uri.EscapeDataString(kvp.Value)}\"));\n url = $\"{url}?{queryString}\";\n }\n using var client = new HttpClient();\n using var request = new HttpRequestMessage(new HttpMethod(\"GET\"), url);\n request.Headers.Add(\"x-auth-token\", ACCESS_TOKEN);\n request.Headers.Add(\"x-client-id\", CLIENT_ID);\n\n using var response = await client.SendAsync(request);\n response.EnsureSuccessStatusCode();\n return await response.Content.ReadAsStringAsync();\n}\n\n// Example usage\nvar query = new Dictionary { {\"language\", \"en\"} };\nvar data = await CallApiAsync(query);\nConsole.WriteLine(data);"},{"lang":"php","label":"PHP","source":"# List of Chapter Reciters\n';\nconst CLIENT_ID = '';\n\nfunction callApi($params = []) {\n $path = \"/resources/chapter_reciters\";\n $url = API_BASE_URL . $path;\n if (!empty($params)) {\n $url .= '?' . http_build_query($params);\n }\n $ch = curl_init($url);\n curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);\n curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');\n curl_setopt($ch, CURLOPT_HTTPHEADER, [\n 'x-auth-token: ' . ACCESS_TOKEN,\n 'x-client-id: ' . CLIENT_ID\n ]);\n\n $response = curl_exec($ch);\n if ($response === false) {\n throw new Exception(curl_error($ch));\n }\n curl_close($ch);\n return $response;\n}\n\n// Example usage\n$params = ['language' => 'en'];\n$data = callApi($params);\necho $data;\n?>"},{"lang":"java","label":"Java","source":"// List of Chapter Reciters\nimport java.io.IOException;\nimport java.util.HashMap;\nimport java.util.Map;\nimport okhttp3.HttpUrl;\nimport okhttp3.OkHttpClient;\nimport okhttp3.Request;\nimport okhttp3.RequestBody;\nimport okhttp3.Response;\n\npublic class Main {\n private static final String API_BASE_URL = \"https://apis.quran.foundation/content/api/v4\";\n private static final String ACCESS_TOKEN = \"\";\n private static final String CLIENT_ID = \"\";\n\n public static String callApi(Map params) throws IOException {\n String path = \"/resources/chapter_reciters\";\n HttpUrl.Builder urlBuilder = HttpUrl.parse(API_BASE_URL + path).newBuilder();\n if (params != null) {\n for (Map.Entry entry : params.entrySet()) {\n urlBuilder.addQueryParameter(entry.getKey(), entry.getValue());\n }\n }\n String method = \"GET\";\n RequestBody requestBody = method.equals(\"GET\") ? null : RequestBody.create(new byte[0]);\n Request request = new Request.Builder()\n .url(urlBuilder.build())\n .addHeader(\"x-auth-token\", ACCESS_TOKEN)\n .addHeader(\"x-client-id\", CLIENT_ID)\n .method(method, requestBody)\n .build();\n\n OkHttpClient client = new OkHttpClient();\n Response response = client.newCall(request).execute();\n return response.body().string();\n }\n\n public static void main(String[] args) throws Exception {\n Map params = new HashMap<>();\n params.put(\"language\", \"en\");\n String data = callApi(params);\n System.out.println(data);\n }\n}"},{"lang":"powershell","label":"PowerShell","source":"# List of Chapter Reciters\n$API_BASE_URL = \"https://apis.quran.foundation/content/api/v4\"\n$ACCESS_TOKEN = \"\"\n$CLIENT_ID = \"\"\n\nfunction Call-Api([hashtable]$params = @{}) {\n $path = \"/resources/chapter_reciters\"\n $url = \"$API_BASE_URL$path\"\n if ($params.Count -gt 0) {\n $query = ($params.GetEnumerator() | ForEach-Object {\n \"$($_.Key)=$([System.Uri]::EscapeDataString([string]$_.Value))\"\n }) -join \"&\"\n $url = \"$url?$query\"\n }\n $headers = @{\n \"x-auth-token\" = $ACCESS_TOKEN\n \"x-client-id\" = $CLIENT_ID\n }\n\n Invoke-RestMethod -Method GET -Uri $url -Headers $headers\n}\n\n# Example usage\n$params = @{ language = \"en\" }\n$data = Call-Api($params)\nWrite-Output $data"},{"lang":"bash","label":"cURL","source":"# List of Chapter Reciters\ncurl -X GET \\\n 'https://apis.quran.foundation/content/api/v4/resources/chapter_reciters?language=en' \\\n -H 'x-auth-token: ' \\\n -H 'x-client-id: '"},{"lang":"text","label":"🤖 AI Prompt","source":"Implement a function to list of chapter reciters using the Quran Foundation API.\n\nEndpoint: GET /resources/chapter_reciters\nBase URL: https://apis.quran.foundation/content/api/v4\n\nRequired Headers (copy exactly):\n x-auth-token: \n x-client-id: \nOptional Query Parameters:\n language: Name of reciters in specific language. Will fallback to English if we don't have names in specific language.\n\nNotes:\n This endpoint returns chapter-reciter IDs.\n Use these IDs with `/chapter_recitations/{reciter_id}`, `/chapter_recitations/{reciter_id}/{chapter_number}`, `/audio/reciters/{reciter_id}/timestamp`, and `/audio/reciters/{reciter_id}/lookup`.\n These IDs are not interchangeable with ayah-by-ayah recitation IDs from `/resources/recitations`.\n\nImplementation Requirements:\n1. Build the request URL: {baseUrl}/resources/chapter_reciters?{queryParams}\n2. Inject both required headers on every request\n3. Handle errors safely:\n - 401: Token expired → re-request token and retry once\n - 403: Access denied → check client credentials\n - 429: Rate limited → implement exponential backoff\n\nAcceptance Checklist:\n- [ ] Function accepts optional parameters\n- [ ] Headers x-auth-token and x-client-id are sent\n- [ ] 401/403/429 errors are handled gracefully"}]}],"method":"get","path":"/resources/chapter_reciters","servers":[{"url":"https://apis-prelive.quran.foundation/content/api/v4","description":"Pre-production Server"},{"url":"https://apis.quran.foundation/content/api/v4","description":"Production Server"}],"security":[{"x-auth-token":[],"x-client-id":[]}],"securitySchemes":{"x-auth-token":{"type":"apiKey","description":"The access token required for accessing the endpoints.","name":"x-auth-token","in":"header"},"x-client-id":{"type":"apiKey","description":"Your client Id","name":"x-client-id","in":"header"}},"info":{"title":"Content APIs","description":"Quran.Foundation Content APIs offer programmatic access to the Quran's core content like chapters, verses, recitations, translations, and more, distinct from user-specific data like notes and bookmarks provided by [User-related APIs](/docs/category/user-related-apis).\n\n:::important Integrity of Translations\nPlease **disable any automatic browser-translation features** (e.g. Google-Translate-in-Chrome) when displaying text returned by the *Translations* endpoints. \nRe-translating an already vetted Quranic translation can introduce serious semantic errors.\n:::\n\n ## How to get access \n\n We are using OAuth2 flows to authenticate and authorize requests. To get started, you need to [get an access token](/docs/tutorials/oidc/getting-started-with-oauth2#obtaining-oauth-20-client-credentials) to make requests to our APIs. Since the APIs are not user-related, you will need to use the `client_credentials` grant type and [`content` scope](/docs/user_related_apis_versioned/scopes#content) when sending a request to [The OAuth 2.0 Token Endpoint](/docs/oauth2_apis_versioned/oauth-2-token-exchange) to get the access token. \n\n```mermaid\nsequenceDiagram\n participant App as Your App\n participant Auth as Quran.Foundation
Authorization Server\n participant API as Quran.Foundation
Resources Server\n\n App->>Auth: Request Token with Client Credentials\n Auth-->>App: Token Response (access_token)\n App->>API: Use token to call API\n API-->>App: Requested resource\n\n Note over App,Auth: Access token expires (1 hour)\n\n App->>Auth: Re-issue access_token using client_credentials\n Auth-->>App: New access_token\n```\n\n After getting a valid access token, each request to get resources will have to include 2 headers mentioned below: `x-auth-token` and `x-client-id`. This spec also includes a small subset of Quran Reflect post-read endpoints that are compatible with the `client_credentials` grant. These operations still require `x-auth-token` and `x-client-id`, but they do not use the `content` scope. Use `post.read` for `/quran-reflect/v1/posts/feed`, `/quran-reflect/v1/posts/{id}`, and `/quran-reflect/v1/posts/user-posts/{id}`. Use `comment.read` for `/quran-reflect/v1/posts/{id}/comments` and `/quran-reflect/v1/posts/{id}/all-comments`. These are Quran Reflect gateway endpoints, not `/content/api/v4/...` endpoints.","version":"v4"},"postman":{"name":"List of Chapter Reciters","description":{"content":"Get list of available chapter reciters. Use these IDs with `/chapter_recitations/{reciter_id}`, `/chapter_recitations/{reciter_id}/{chapter_number}`, `/audio/reciters/{reciter_id}/timestamp`, and `/audio/reciters/{reciter_id}/lookup`. These IDs are not interchangeable with ayah-by-ayah recitation IDs from `/resources/recitations`.","type":"text/plain"},"url":{"path":["resources","chapter_reciters"],"host":["{{baseUrl}}"],"query":[{"disabled":false,"description":{"content":"Name of reciters in specific language. Will fallback to English if we don't have names in specific language.","type":"text/plain"},"key":"language","value":""}],"variable":[]},"header":[{"key":"Accept","value":"application/json"}],"method":"GET"}} +api: {"tags":["Audio"],"description":"Get list of available chapter reciters. Use these IDs with `/chapter_recitations/{reciter_id}`, `/chapter_recitations/{reciter_id}/{chapter_number}`, `/audio/reciters/{reciter_id}/timestamp`, and `/audio/reciters/{reciter_id}/lookup`. These IDs are not interchangeable with ayah-by-ayah recitation IDs from `/resources/recitations`.","operationId":"chapter-reciters","parameters":[{"name":"language","in":"query","description":"Name of reciters in specific language. Will fallback to English if we don't have names in specific language.","schema":{"type":"string","default":"en"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","required":["reciters"],"properties":{"reciters":{"type":"array","items":{"title":"Chapter Reciters","required":["id","name","style","qirat","reciter_id","beta"],"type":"object","properties":{"id":{"type":"integer","description":"Chapter-reciter ID. Use it as `reciter_id` in [/chapter_recitations/{reciter_id}](/docs/content_apis_versioned/chapter-reciter-audio-files)."},"reciter_id":{"type":"integer","nullable":true,"description":"ID of the person reciting. Several chapter reciters (for example, Murattal and Mujawwad styles of the same reciter) can share one `reciter_id`."},"name":{"type":"string","description":"Name of reciter in English"},"beta":{"type":"boolean","description":"`true` when Quran.com marks the recitation as beta."},"style":{"type":"object","properties":{"name":{"type":"string","nullable":true},"language_name":{"type":"string"}},"required":["language_name"]},"qirat":{"type":"object","properties":{"name":{"type":"string","nullable":true},"language_name":{"type":"string"}},"required":["language_name"]},"translated_name":{"nullable":true,"allOf":[{"title":"TranslatedName","required":["language_name","name"],"type":"object","properties":{"language_name":{"type":"string","default":"english"},"name":{"type":"string","description":"Name of the resource in specific language."}},"example":{"language_name":"english","name":"The Opener"}}]}},"example":{"id":4,"reciter_id":3,"name":"Abu Bakr al-Shatri","beta":false,"style":{"name":"Murattal","language_name":"english"},"qirat":{"name":"Hafs","language_name":"english"},"translated_name":{"name":"Abu Bakr al-Shatri","language_name":"english"}}}}}},"examples":{"default_success":{"summary":"Successful response","value":{"reciters":[{"id":4,"reciter_id":3,"name":"Abu Bakr al-Shatri","beta":false,"style":{"name":"Murattal","language_name":"english"},"qirat":{"name":"Hafs","language_name":"english"},"translated_name":{"name":"Abu Bakr al-Shatri","language_name":"english"}}]}}}}}},"400":{"description":"Will be returned when the request is invalid e.g. request is missing required headers or with invalid query parameters.","content":{"application/json":{"schema":{"title":"invalidRequestResponse","type":"object","properties":{"message":{"type":"string"},"type":{"type":"string","enum":["gateway_timeout","service_unavailable","bad_gateway","internal_server_error","unprocessable_entity","not_found","forbidden","unauthorized","invalid_request","invalid_token","insufficient_scope","service_error","invalid_path","rate_limit_exceeded"]},"success":{"type":"boolean"}}},"example":{"message":"The request is missing required headers or is invalid","type":"invalid_request","success":false}}}},"401":{"description":"Will be returned when the request is unauthorized.","content":{"application/json":{"schema":{"title":"unauthorizedResponse","type":"object","properties":{"message":{"type":"string"},"type":{"type":"string","enum":["gateway_timeout","service_unavailable","bad_gateway","internal_server_error","unprocessable_entity","not_found","forbidden","unauthorized","invalid_request","invalid_token","insufficient_scope","service_error","invalid_path","rate_limit_exceeded"]},"success":{"type":"boolean"}}},"example":{"message":"The request requires user authentication","type":"unauthorized","success":false}}}},"403":{"description":"The request is forbidden, for example because a valid access token lacks the required scope or the client lacks permission.","content":{"application/json":{"schema":{"title":"forbiddenResponse","type":"object","properties":{"message":{"type":"string"},"type":{"type":"string","enum":["gateway_timeout","service_unavailable","bad_gateway","internal_server_error","unprocessable_entity","not_found","forbidden","unauthorized","invalid_request","invalid_token","insufficient_scope","service_error","invalid_path","rate_limit_exceeded"]},"success":{"type":"boolean"}}},"example":{"message":"The server understood the request, but refuses to authorize it","type":"forbidden","success":false}}}},"404":{"description":"Not Found. The resource being accessed does not exist.","content":{"application/json":{"schema":{"title":"notFoundResponse","type":"object","properties":{"message":{"type":"string"},"type":{"type":"string","enum":["gateway_timeout","service_unavailable","bad_gateway","internal_server_error","unprocessable_entity","not_found","forbidden","unauthorized","invalid_request","invalid_token","insufficient_scope","service_error","invalid_path","rate_limit_exceeded"]},"success":{"type":"boolean"}}},"example":{"message":"The requested resource could not be found","type":"not_found","success":false}}}},"422":{"description":"Validation Error. The request includes one or more invalid params. Please check the request params and try again.","content":{"application/json":{"schema":{"title":"unprocessableEntityResponse","type":"object","properties":{"message":{"type":"string"},"type":{"type":"string","enum":["gateway_timeout","service_unavailable","bad_gateway","internal_server_error","unprocessable_entity","not_found","forbidden","unauthorized","invalid_request","invalid_token","insufficient_scope","service_error","invalid_path","rate_limit_exceeded"]},"success":{"type":"boolean"}}},"example":{"message":"The request was well-formed but was unable to be followed due to semantic errors","type":"unprocessable_entity","success":false}}}},"429":{"description":"Rate-limit exceeded","content":{"application/json":{"schema":{"title":"rateLimitExceededResponse","type":"object","properties":{"message":{"type":"string"},"type":{"type":"string","enum":["gateway_timeout","service_unavailable","bad_gateway","internal_server_error","unprocessable_entity","not_found","forbidden","unauthorized","invalid_request","invalid_token","insufficient_scope","service_error","invalid_path","rate_limit_exceeded"]},"success":{"type":"boolean"}}},"example":{"message":"Too many requests, please try again later","type":"rate_limit_exceeded","success":false}}}},"500":{"description":"Server Error. Something went wrong, try again later.","content":{"application/json":{"schema":{"title":"internalServerErrorResponse","type":"object","properties":{"message":{"type":"string"},"type":{"type":"string","enum":["gateway_timeout","service_unavailable","bad_gateway","internal_server_error","unprocessable_entity","not_found","forbidden","unauthorized","invalid_request","invalid_token","insufficient_scope","service_error","invalid_path","rate_limit_exceeded"]},"success":{"type":"boolean"}}},"example":{"message":"The server encountered an internal error and was unable to complete your request","type":"internal_server_error","success":false}}}},"502":{"description":"Bad Gateway","content":{"application/json":{"schema":{"title":"badGatewayResponse","type":"object","properties":{"message":{"type":"string"},"type":{"type":"string","enum":["gateway_timeout","service_unavailable","bad_gateway","internal_server_error","unprocessable_entity","not_found","forbidden","unauthorized","invalid_request","invalid_token","insufficient_scope","service_error","invalid_path","rate_limit_exceeded"]},"success":{"type":"boolean"}}},"example":{"message":"The server was acting as a gateway or proxy and received an invalid response from the upstream server","type":"bad_gateway","success":false}}}},"503":{"description":"Service Unavailable","content":{"application/json":{"schema":{"title":"serviceUnavailableResponse","type":"object","properties":{"message":{"type":"string"},"type":{"type":"string","enum":["gateway_timeout","service_unavailable","bad_gateway","internal_server_error","unprocessable_entity","not_found","forbidden","unauthorized","invalid_request","invalid_token","insufficient_scope","service_error","invalid_path","rate_limit_exceeded"]},"success":{"type":"boolean"}}},"example":{"message":"The server is currently unable to handle the request due to a temporary overload or scheduled maintenance","type":"service_unavailable","success":false}}}},"504":{"description":"Gateway Timeout","content":{"application/json":{"schema":{"title":"gatewayTimeoutResponse","type":"object","properties":{"message":{"type":"string"},"type":{"type":"string","enum":["gateway_timeout","service_unavailable","bad_gateway","internal_server_error","unprocessable_entity","not_found","forbidden","unauthorized","invalid_request","invalid_token","insufficient_scope","service_error","invalid_path","rate_limit_exceeded"]},"success":{"type":"boolean"}}},"example":{"message":"The server was acting as a gateway or proxy and did not receive a timely response from the upstream server","type":"gateway_timeout","success":false}}}}},"x-code-samples":[{"lang":"javascript","label":"Node.js","source":"// List of Chapter Reciters\nconst axios = require('axios');\n\nconst API_BASE_URL = 'https://apis.quran.foundation/content/api/v4';\nconst ACCESS_TOKEN = '';\nconst CLIENT_ID = '';\n\nasync function callApi(options = {}) {\n const response = await axios.get(\n `${API_BASE_URL}/resources/chapter_reciters`,\n {\n headers: {\n 'x-auth-token': ACCESS_TOKEN,\n 'x-client-id': CLIENT_ID\n },\n params: options\n }\n );\n return response.data;\n}\n\n// Example usage\ncallApi({\"language\":\"en\"})\n .then(data => console.log(data))\n .catch(err => console.error(err.response?.status, err.message));"},{"lang":"python","label":"Python","source":"# List of Chapter Reciters\nimport requests\n\nAPI_BASE_URL = 'https://apis.quran.foundation/content/api/v4'\nACCESS_TOKEN = ''\nCLIENT_ID = ''\n\ndef call_api(language=None):\n params = {k: v for k, v in {'language': language}.items() if v is not None}\n \n response = requests.get(\n f'{API_BASE_URL}/resources/chapter_reciters',\n headers={\n 'x-auth-token': ACCESS_TOKEN,\n 'x-client-id': CLIENT_ID\n },\n params=params\n )\n response.raise_for_status()\n return response.json()\n\n# Example usage\ntry:\n data = call_api(language=\"en\")\n print(data)\nexcept requests.HTTPError as e:\n print(f'Error {e.response.status_code}: {e}')"},{"lang":"go","label":"Go","source":"// List of Chapter Reciters\npackage main\n\nimport (\n \"fmt\"\n \"io\"\n \"net/http\"\n \"net/url\"\n)\n\nconst API_BASE_URL = \"https://apis.quran.foundation/content/api/v4\"\nconst ACCESS_TOKEN = \"\"\nconst CLIENT_ID = \"\"\n\nfunc callApi(params map[string]string) (string, error) {\n path := \"/resources/chapter_reciters\"\n endpoint := API_BASE_URL + path\n if params != nil && len(params) > 0 {\n values := url.Values{}\n for k, v := range params {\n values.Set(k, v)\n }\n endpoint = endpoint + \"?\" + values.Encode()\n }\n\n req, err := http.NewRequest(\"GET\", endpoint, nil)\n if err != nil {\n return \"\", err\n }\n req.Header.Set(\"x-auth-token\", ACCESS_TOKEN)\n req.Header.Set(\"x-client-id\", CLIENT_ID)\n\n resp, err := http.DefaultClient.Do(req)\n if err != nil {\n return \"\", err\n }\n defer resp.Body.Close()\n\n body, err := io.ReadAll(resp.Body)\n if err != nil {\n return \"\", err\n }\n return string(body), nil\n}\n\n// Example usage\nfunc main() {\n params := map[string]string{\"language\": \"en\"}\n data, err := callApi(params)\n if err != nil {\n fmt.Println(\"Error:\", err)\n return\n }\n fmt.Println(data)\n}"},{"lang":"ruby","label":"Ruby","source":"# List of Chapter Reciters\nrequire \"net/http\"\nrequire \"uri\"\n\nAPI_BASE_URL = \"https://apis.quran.foundation/content/api/v4\"\nACCESS_TOKEN = \"\"\nCLIENT_ID = \"\"\n\ndef call_api(params = {})\n path = \"/resources/chapter_reciters\"\n uri = URI(API_BASE_URL + path)\n uri.query = URI.encode_www_form(params) if params && !params.empty?\n request_class = Net::HTTP.const_get(\"Get\")\n request = request_class.new(uri)\n request[\"x-auth-token\"] = ACCESS_TOKEN\n request[\"x-client-id\"] = CLIENT_ID\n\n response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|\n http.request(request)\n end\n\n response.body\nend\n\n# Example usage\nparams = { \"language\" => \"en\" }\ndata = call_api(params)\nputs data"},{"lang":"csharp","label":"C#","source":"// List of Chapter Reciters\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Net.Http;\nusing System.Threading.Tasks;\n\nconst string API_BASE_URL = \"https://apis.quran.foundation/content/api/v4\";\nconst string ACCESS_TOKEN = \"\";\nconst string CLIENT_ID = \"\";\n\nstatic async Task CallApiAsync(Dictionary query = null)\n{\n var path = $@\"/resources/chapter_reciters\";\n var url = API_BASE_URL + path;\n if (query != null && query.Count > 0)\n {\n var queryString = string.Join(\"&\", query.Select(kvp =>\n $\"{Uri.EscapeDataString(kvp.Key)}={Uri.EscapeDataString(kvp.Value)}\"));\n url = $\"{url}?{queryString}\";\n }\n using var client = new HttpClient();\n using var request = new HttpRequestMessage(new HttpMethod(\"GET\"), url);\n request.Headers.Add(\"x-auth-token\", ACCESS_TOKEN);\n request.Headers.Add(\"x-client-id\", CLIENT_ID);\n\n using var response = await client.SendAsync(request);\n response.EnsureSuccessStatusCode();\n return await response.Content.ReadAsStringAsync();\n}\n\n// Example usage\nvar query = new Dictionary { {\"language\", \"en\"} };\nvar data = await CallApiAsync(query);\nConsole.WriteLine(data);"},{"lang":"php","label":"PHP","source":"# List of Chapter Reciters\n';\nconst CLIENT_ID = '';\n\nfunction callApi($params = []) {\n $path = \"/resources/chapter_reciters\";\n $url = API_BASE_URL . $path;\n if (!empty($params)) {\n $url .= '?' . http_build_query($params);\n }\n $ch = curl_init($url);\n curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);\n curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');\n curl_setopt($ch, CURLOPT_HTTPHEADER, [\n 'x-auth-token: ' . ACCESS_TOKEN,\n 'x-client-id: ' . CLIENT_ID\n ]);\n\n $response = curl_exec($ch);\n if ($response === false) {\n throw new Exception(curl_error($ch));\n }\n curl_close($ch);\n return $response;\n}\n\n// Example usage\n$params = ['language' => 'en'];\n$data = callApi($params);\necho $data;\n?>"},{"lang":"java","label":"Java","source":"// List of Chapter Reciters\nimport java.io.IOException;\nimport java.util.HashMap;\nimport java.util.Map;\nimport okhttp3.HttpUrl;\nimport okhttp3.OkHttpClient;\nimport okhttp3.Request;\nimport okhttp3.RequestBody;\nimport okhttp3.Response;\n\npublic class Main {\n private static final String API_BASE_URL = \"https://apis.quran.foundation/content/api/v4\";\n private static final String ACCESS_TOKEN = \"\";\n private static final String CLIENT_ID = \"\";\n\n public static String callApi(Map params) throws IOException {\n String path = \"/resources/chapter_reciters\";\n HttpUrl.Builder urlBuilder = HttpUrl.parse(API_BASE_URL + path).newBuilder();\n if (params != null) {\n for (Map.Entry entry : params.entrySet()) {\n urlBuilder.addQueryParameter(entry.getKey(), entry.getValue());\n }\n }\n String method = \"GET\";\n RequestBody requestBody = method.equals(\"GET\") ? null : RequestBody.create(new byte[0]);\n Request request = new Request.Builder()\n .url(urlBuilder.build())\n .addHeader(\"x-auth-token\", ACCESS_TOKEN)\n .addHeader(\"x-client-id\", CLIENT_ID)\n .method(method, requestBody)\n .build();\n\n OkHttpClient client = new OkHttpClient();\n Response response = client.newCall(request).execute();\n return response.body().string();\n }\n\n public static void main(String[] args) throws Exception {\n Map params = new HashMap<>();\n params.put(\"language\", \"en\");\n String data = callApi(params);\n System.out.println(data);\n }\n}"},{"lang":"powershell","label":"PowerShell","source":"# List of Chapter Reciters\n$API_BASE_URL = \"https://apis.quran.foundation/content/api/v4\"\n$ACCESS_TOKEN = \"\"\n$CLIENT_ID = \"\"\n\nfunction Call-Api([hashtable]$params = @{}) {\n $path = \"/resources/chapter_reciters\"\n $url = \"$API_BASE_URL$path\"\n if ($params.Count -gt 0) {\n $query = ($params.GetEnumerator() | ForEach-Object {\n \"$($_.Key)=$([System.Uri]::EscapeDataString([string]$_.Value))\"\n }) -join \"&\"\n $url = \"$url?$query\"\n }\n $headers = @{\n \"x-auth-token\" = $ACCESS_TOKEN\n \"x-client-id\" = $CLIENT_ID\n }\n\n Invoke-RestMethod -Method GET -Uri $url -Headers $headers\n}\n\n# Example usage\n$params = @{ language = \"en\" }\n$data = Call-Api($params)\nWrite-Output $data"},{"lang":"bash","label":"cURL","source":"# List of Chapter Reciters\ncurl -X GET \\\n 'https://apis.quran.foundation/content/api/v4/resources/chapter_reciters?language=en' \\\n -H 'x-auth-token: ' \\\n -H 'x-client-id: '"},{"lang":"text","label":"🤖 AI Prompt","source":"Implement a function to list of chapter reciters using the Quran Foundation API.\n\nEndpoint: GET /resources/chapter_reciters\nBase URL: https://apis.quran.foundation/content/api/v4\n\nRequired Headers (copy exactly):\n x-auth-token: \n x-client-id: \nOptional Query Parameters:\n language: Name of reciters in specific language. Will fallback to English if we don't have names in specific language.\n\nNotes:\n This endpoint returns chapter-reciter IDs.\n Use these IDs with `/chapter_recitations/{reciter_id}`, `/chapter_recitations/{reciter_id}/{chapter_number}`, `/audio/reciters/{reciter_id}/timestamp`, and `/audio/reciters/{reciter_id}/lookup`.\n These IDs are not interchangeable with ayah-by-ayah recitation IDs from `/resources/recitations`.\n\nImplementation Requirements:\n1. Build the request URL: {baseUrl}/resources/chapter_reciters?{queryParams}\n2. Inject both required headers on every request\n3. Handle errors safely:\n - 401: Token expired → re-request token and retry once\n - 403: Access denied → check client credentials\n - 429: Rate limited → implement exponential backoff\n\nAcceptance Checklist:\n- [ ] Function accepts optional parameters\n- [ ] Headers x-auth-token and x-client-id are sent\n- [ ] 401/403/429 errors are handled gracefully"}],"x-qf-scopes":{"contractVersion":"content-scopes/v1","contractSha256":"0bba34fad8ac4ecc6d782eff14ae8f5cf50bac1784c832d5d1eb7d7f8be0ed36","contractStatus":"approved","routeId":"content.v4.chapter-reciters","service":"content","anyOf":["content.read","content","content.audio.read"],"legacyAnyOf":["content.read","content"],"granularAnyOf":["content.audio.read"],"deprecatedForNewClients":["content.read","content"],"quotaBuckets":["content.read","content"],"rateLimitPolicyId":"preserve-existing-content-read-policy","responseBoundary":"endpoint-family-not-data-isolation","transport":{"note":"Both headers are required together. These are not OAuth2 bearer credentials.","headers":["x-auth-token","x-client-id"]}},"extensions":[{"key":"x-code-samples","value":[{"lang":"javascript","label":"Node.js","source":"// List of Chapter Reciters\nconst axios = require('axios');\n\nconst API_BASE_URL = 'https://apis.quran.foundation/content/api/v4';\nconst ACCESS_TOKEN = '';\nconst CLIENT_ID = '';\n\nasync function callApi(options = {}) {\n const response = await axios.get(\n `${API_BASE_URL}/resources/chapter_reciters`,\n {\n headers: {\n 'x-auth-token': ACCESS_TOKEN,\n 'x-client-id': CLIENT_ID\n },\n params: options\n }\n );\n return response.data;\n}\n\n// Example usage\ncallApi({\"language\":\"en\"})\n .then(data => console.log(data))\n .catch(err => console.error(err.response?.status, err.message));"},{"lang":"python","label":"Python","source":"# List of Chapter Reciters\nimport requests\n\nAPI_BASE_URL = 'https://apis.quran.foundation/content/api/v4'\nACCESS_TOKEN = ''\nCLIENT_ID = ''\n\ndef call_api(language=None):\n params = {k: v for k, v in {'language': language}.items() if v is not None}\n \n response = requests.get(\n f'{API_BASE_URL}/resources/chapter_reciters',\n headers={\n 'x-auth-token': ACCESS_TOKEN,\n 'x-client-id': CLIENT_ID\n },\n params=params\n )\n response.raise_for_status()\n return response.json()\n\n# Example usage\ntry:\n data = call_api(language=\"en\")\n print(data)\nexcept requests.HTTPError as e:\n print(f'Error {e.response.status_code}: {e}')"},{"lang":"go","label":"Go","source":"// List of Chapter Reciters\npackage main\n\nimport (\n \"fmt\"\n \"io\"\n \"net/http\"\n \"net/url\"\n)\n\nconst API_BASE_URL = \"https://apis.quran.foundation/content/api/v4\"\nconst ACCESS_TOKEN = \"\"\nconst CLIENT_ID = \"\"\n\nfunc callApi(params map[string]string) (string, error) {\n path := \"/resources/chapter_reciters\"\n endpoint := API_BASE_URL + path\n if params != nil && len(params) > 0 {\n values := url.Values{}\n for k, v := range params {\n values.Set(k, v)\n }\n endpoint = endpoint + \"?\" + values.Encode()\n }\n\n req, err := http.NewRequest(\"GET\", endpoint, nil)\n if err != nil {\n return \"\", err\n }\n req.Header.Set(\"x-auth-token\", ACCESS_TOKEN)\n req.Header.Set(\"x-client-id\", CLIENT_ID)\n\n resp, err := http.DefaultClient.Do(req)\n if err != nil {\n return \"\", err\n }\n defer resp.Body.Close()\n\n body, err := io.ReadAll(resp.Body)\n if err != nil {\n return \"\", err\n }\n return string(body), nil\n}\n\n// Example usage\nfunc main() {\n params := map[string]string{\"language\": \"en\"}\n data, err := callApi(params)\n if err != nil {\n fmt.Println(\"Error:\", err)\n return\n }\n fmt.Println(data)\n}"},{"lang":"ruby","label":"Ruby","source":"# List of Chapter Reciters\nrequire \"net/http\"\nrequire \"uri\"\n\nAPI_BASE_URL = \"https://apis.quran.foundation/content/api/v4\"\nACCESS_TOKEN = \"\"\nCLIENT_ID = \"\"\n\ndef call_api(params = {})\n path = \"/resources/chapter_reciters\"\n uri = URI(API_BASE_URL + path)\n uri.query = URI.encode_www_form(params) if params && !params.empty?\n request_class = Net::HTTP.const_get(\"Get\")\n request = request_class.new(uri)\n request[\"x-auth-token\"] = ACCESS_TOKEN\n request[\"x-client-id\"] = CLIENT_ID\n\n response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|\n http.request(request)\n end\n\n response.body\nend\n\n# Example usage\nparams = { \"language\" => \"en\" }\ndata = call_api(params)\nputs data"},{"lang":"csharp","label":"C#","source":"// List of Chapter Reciters\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Net.Http;\nusing System.Threading.Tasks;\n\nconst string API_BASE_URL = \"https://apis.quran.foundation/content/api/v4\";\nconst string ACCESS_TOKEN = \"\";\nconst string CLIENT_ID = \"\";\n\nstatic async Task CallApiAsync(Dictionary query = null)\n{\n var path = $@\"/resources/chapter_reciters\";\n var url = API_BASE_URL + path;\n if (query != null && query.Count > 0)\n {\n var queryString = string.Join(\"&\", query.Select(kvp =>\n $\"{Uri.EscapeDataString(kvp.Key)}={Uri.EscapeDataString(kvp.Value)}\"));\n url = $\"{url}?{queryString}\";\n }\n using var client = new HttpClient();\n using var request = new HttpRequestMessage(new HttpMethod(\"GET\"), url);\n request.Headers.Add(\"x-auth-token\", ACCESS_TOKEN);\n request.Headers.Add(\"x-client-id\", CLIENT_ID);\n\n using var response = await client.SendAsync(request);\n response.EnsureSuccessStatusCode();\n return await response.Content.ReadAsStringAsync();\n}\n\n// Example usage\nvar query = new Dictionary { {\"language\", \"en\"} };\nvar data = await CallApiAsync(query);\nConsole.WriteLine(data);"},{"lang":"php","label":"PHP","source":"# List of Chapter Reciters\n';\nconst CLIENT_ID = '';\n\nfunction callApi($params = []) {\n $path = \"/resources/chapter_reciters\";\n $url = API_BASE_URL . $path;\n if (!empty($params)) {\n $url .= '?' . http_build_query($params);\n }\n $ch = curl_init($url);\n curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);\n curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');\n curl_setopt($ch, CURLOPT_HTTPHEADER, [\n 'x-auth-token: ' . ACCESS_TOKEN,\n 'x-client-id: ' . CLIENT_ID\n ]);\n\n $response = curl_exec($ch);\n if ($response === false) {\n throw new Exception(curl_error($ch));\n }\n curl_close($ch);\n return $response;\n}\n\n// Example usage\n$params = ['language' => 'en'];\n$data = callApi($params);\necho $data;\n?>"},{"lang":"java","label":"Java","source":"// List of Chapter Reciters\nimport java.io.IOException;\nimport java.util.HashMap;\nimport java.util.Map;\nimport okhttp3.HttpUrl;\nimport okhttp3.OkHttpClient;\nimport okhttp3.Request;\nimport okhttp3.RequestBody;\nimport okhttp3.Response;\n\npublic class Main {\n private static final String API_BASE_URL = \"https://apis.quran.foundation/content/api/v4\";\n private static final String ACCESS_TOKEN = \"\";\n private static final String CLIENT_ID = \"\";\n\n public static String callApi(Map params) throws IOException {\n String path = \"/resources/chapter_reciters\";\n HttpUrl.Builder urlBuilder = HttpUrl.parse(API_BASE_URL + path).newBuilder();\n if (params != null) {\n for (Map.Entry entry : params.entrySet()) {\n urlBuilder.addQueryParameter(entry.getKey(), entry.getValue());\n }\n }\n String method = \"GET\";\n RequestBody requestBody = method.equals(\"GET\") ? null : RequestBody.create(new byte[0]);\n Request request = new Request.Builder()\n .url(urlBuilder.build())\n .addHeader(\"x-auth-token\", ACCESS_TOKEN)\n .addHeader(\"x-client-id\", CLIENT_ID)\n .method(method, requestBody)\n .build();\n\n OkHttpClient client = new OkHttpClient();\n Response response = client.newCall(request).execute();\n return response.body().string();\n }\n\n public static void main(String[] args) throws Exception {\n Map params = new HashMap<>();\n params.put(\"language\", \"en\");\n String data = callApi(params);\n System.out.println(data);\n }\n}"},{"lang":"powershell","label":"PowerShell","source":"# List of Chapter Reciters\n$API_BASE_URL = \"https://apis.quran.foundation/content/api/v4\"\n$ACCESS_TOKEN = \"\"\n$CLIENT_ID = \"\"\n\nfunction Call-Api([hashtable]$params = @{}) {\n $path = \"/resources/chapter_reciters\"\n $url = \"$API_BASE_URL$path\"\n if ($params.Count -gt 0) {\n $query = ($params.GetEnumerator() | ForEach-Object {\n \"$($_.Key)=$([System.Uri]::EscapeDataString([string]$_.Value))\"\n }) -join \"&\"\n $url = \"$url?$query\"\n }\n $headers = @{\n \"x-auth-token\" = $ACCESS_TOKEN\n \"x-client-id\" = $CLIENT_ID\n }\n\n Invoke-RestMethod -Method GET -Uri $url -Headers $headers\n}\n\n# Example usage\n$params = @{ language = \"en\" }\n$data = Call-Api($params)\nWrite-Output $data"},{"lang":"bash","label":"cURL","source":"# List of Chapter Reciters\ncurl -X GET \\\n 'https://apis.quran.foundation/content/api/v4/resources/chapter_reciters?language=en' \\\n -H 'x-auth-token: ' \\\n -H 'x-client-id: '"},{"lang":"text","label":"🤖 AI Prompt","source":"Implement a function to list of chapter reciters using the Quran Foundation API.\n\nEndpoint: GET /resources/chapter_reciters\nBase URL: https://apis.quran.foundation/content/api/v4\n\nRequired Headers (copy exactly):\n x-auth-token: \n x-client-id: \nOptional Query Parameters:\n language: Name of reciters in specific language. Will fallback to English if we don't have names in specific language.\n\nNotes:\n This endpoint returns chapter-reciter IDs.\n Use these IDs with `/chapter_recitations/{reciter_id}`, `/chapter_recitations/{reciter_id}/{chapter_number}`, `/audio/reciters/{reciter_id}/timestamp`, and `/audio/reciters/{reciter_id}/lookup`.\n These IDs are not interchangeable with ayah-by-ayah recitation IDs from `/resources/recitations`.\n\nImplementation Requirements:\n1. Build the request URL: {baseUrl}/resources/chapter_reciters?{queryParams}\n2. Inject both required headers on every request\n3. Handle errors safely:\n - 401: Token expired → re-request token and retry once\n - 403: Access denied → check client credentials\n - 429: Rate limited → implement exponential backoff\n\nAcceptance Checklist:\n- [ ] Function accepts optional parameters\n- [ ] Headers x-auth-token and x-client-id are sent\n- [ ] 401/403/429 errors are handled gracefully"}]},{"key":"x-qf-scopes","value":{"contractVersion":"content-scopes/v1","contractSha256":"0bba34fad8ac4ecc6d782eff14ae8f5cf50bac1784c832d5d1eb7d7f8be0ed36","contractStatus":"approved","routeId":"content.v4.chapter-reciters","service":"content","anyOf":["content.read","content","content.audio.read"],"legacyAnyOf":["content.read","content"],"granularAnyOf":["content.audio.read"],"deprecatedForNewClients":["content.read","content"],"quotaBuckets":["content.read","content"],"rateLimitPolicyId":"preserve-existing-content-read-policy","responseBoundary":"endpoint-family-not-data-isolation","transport":{"note":"Both headers are required together. These are not OAuth2 bearer credentials.","headers":["x-auth-token","x-client-id"]}}}],"method":"get","path":"/resources/chapter_reciters","servers":[{"url":"https://apis-prelive.quran.foundation/content/api/v4","description":"Pre-production Server — testing and development only; Quran content is limited to Al-Fatihah (surah 1) and Al-Baqarah (surah 2)."},{"url":"https://apis.quran.foundation/content/api/v4","description":"Production Server"}],"security":[{"x-auth-token":[],"x-client-id":[]}],"securitySchemes":{"x-auth-token":{"type":"apiKey","description":"The access token required for accessing the endpoints.","name":"x-auth-token","in":"header"},"x-client-id":{"type":"apiKey","description":"Your client Id","name":"x-client-id","in":"header"}},"info":{"title":"Content APIs","description":"Quran Foundation Content APIs offer programmatic access to the Quran's core content like chapters, verses, recitations, translations, and more, distinct from user-specific data like notes and bookmarks provided by [User-related APIs](/docs/category/user-related-apis).\n\n:::note Prelive Content API limitation\nThe prelive environment is for testing and development only. Its Quran content dataset includes only Al-Fatihah (surah 1) and Al-Baqarah (surah 2). Test content requests using these surahs. For the complete Quran dataset, use the production environment after production access is approved.\n:::\n\n:::important Integrity of Translations\nPlease **disable any automatic browser-translation features** (e.g. Google-Translate-in-Chrome) when displaying text returned by the *Translations* endpoints. \nRe-translating an already vetted Quranic translation can introduce serious semantic errors.\n:::\n\n ## How to get access \n\n We are using OAuth2 flows to authenticate and authorize requests. To get started, you need to [get an access token](/docs/tutorials/oidc/getting-started-with-oauth2#obtaining-oauth-20-client-credentials) to make requests to our APIs. Since the APIs are not user-related, you will need to use the `client_credentials` grant type and [`content` scope](/docs/user_related_apis_versioned/scopes#content) when sending a request to [The OAuth 2.0 Token Endpoint](/docs/oauth2_apis_versioned/oauth-2-token-exchange) to get the access token. \n\n```mermaid\nsequenceDiagram\n participant App as Your App\n participant Auth as Quran Foundation
Authorization Server\n participant API as Quran Foundation
Resources Server\n\n App->>Auth: Request Token with Client Credentials\n Auth-->>App: Token Response (access_token)\n App->>API: Use token to call API\n API-->>App: Requested resource\n\n Note over App,Auth: Access token expires (1 hour)\n\n App->>Auth: Re-issue access_token using client_credentials\n Auth-->>App: New access_token\n```\n\n After getting a valid access token, each request to get resources will have to include 2 headers mentioned below: `x-auth-token` and `x-client-id`. This spec also includes a small subset of Quran Reflect post-read endpoints that are compatible with the `client_credentials` grant. These operations still require `x-auth-token` and `x-client-id`, but they do not use the `content` scope. Use `post.read` for `/quran-reflect/v1/posts/feed`, `/quran-reflect/v1/posts/{id}`, and `/quran-reflect/v1/posts/user-posts/{id}`. Use `comment.read` for `/quran-reflect/v1/posts/{id}/comments` and `/quran-reflect/v1/posts/{id}/all-comments`. These are Quran Reflect gateway endpoints, not `/content/api/v4/...` endpoints. The Qira'at endpoints under `/content/api/v4/qiraat/...` are scope-gated: they require the `qiraat.read` scope (or the parent `qiraat` scope) instead of `content`, so request the Qira'at scope your client has been approved for when you [get an access token](/docs/user_related_apis_versioned/scopes#qiraat).","version":"v4"},"postman":{"name":"List of Chapter Reciters","description":{"content":"Get list of available chapter reciters. Use these IDs with `/chapter_recitations/{reciter_id}`, `/chapter_recitations/{reciter_id}/{chapter_number}`, `/audio/reciters/{reciter_id}/timestamp`, and `/audio/reciters/{reciter_id}/lookup`. These IDs are not interchangeable with ayah-by-ayah recitation IDs from `/resources/recitations`.","type":"text/plain"},"url":{"path":["resources","chapter_reciters"],"host":["{{baseUrl}}"],"query":[{"disabled":false,"description":{"content":"Name of reciters in specific language. Will fallback to English if we don't have names in specific language.","type":"text/plain"},"key":"language","value":""}],"variable":[]},"header":[{"key":"Accept","value":"application/json"}],"method":"GET"}} sidebar_class_name: "get api-method" info_path: docs/content_apis_versioned/4.0.0/content-apis custom_edit_url: null @@ -31,7 +31,7 @@ Get list of available chapter reciters. Use these IDs with `/chapter_recitations Successful response -
Schema
    reciters object[] required
  • Array [
  • style object required
    qirat object required
    translated_name object nullable
  • ]

Successful response

+
Schema
    reciters object[] required
  • Array [
  • style object required
    qirat object required
    translated_name object nullable
  • ]

Successful response

Will be returned when the request is invalid e.g. request is missing required headers or with invalid query parameters. @@ -41,7 +41,7 @@ Will be returned when the request is unauthorized.
Schema
-Forbidden error. Can either be due to access token not being passed, having been expired or the caller trying to access a resource without enough permissions. +The request is forbidden, for example because a valid access token lacks the required scope or the client lacks permission.
Schema
diff --git a/docs/content_apis_versioned/chapter-reciter-audio-file.api.mdx b/docs/content_apis_versioned/chapter-reciter-audio-file.api.mdx index 8a978fdf..2d4b232b 100644 --- a/docs/content_apis_versioned/chapter-reciter-audio-file.api.mdx +++ b/docs/content_apis_versioned/chapter-reciter-audio-file.api.mdx @@ -5,7 +5,7 @@ description: "Get chapter's audio file of a reciter. Supports `segments` (boolea sidebar_label: "Get chapter's audio file of a reciter" hide_title: true hide_table_of_contents: true -api: {"tags":["Audio"],"description":"Get chapter's audio file of a reciter. Supports `segments` (boolean query param; default `false`). When `segments=true`, verse-level timestamp entries include `segments` ([word_index, start_ms, end_ms]). All time values are milliseconds.","operationId":"chapter-reciter-audio-file","parameters":[{"name":"reciter_id","in":"path","description":"Chapter-reciter ID from [/resources/chapter_reciters](/docs/content_apis_versioned/chapter-reciters). Do not use ayah-by-ayah recitation IDs from [/resources/recitations](/docs/content_apis_versioned/recitations) here.","required":true,"schema":{"type":"number"}},{"name":"chapter_number","in":"path","description":"The number of the chapter","required":true,"schema":{"maximum":114,"minimum":1,"type":"number"}},{"name":"segments","in":"query","required":false,"schema":{"type":"boolean","default":false},"description":"If true, each verse timestamp includes a `segments` array of [word_index, start_ms, end_ms] triplets. Time values are in milliseconds."}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"audio_file":{"type":"object","required":["id","chapter_id","file_size","format","audio_url"],"properties":{"id":{"type":"integer","example":457},"chapter_id":{"type":"integer","example":1},"file_size":{"type":"number","format":"float","description":"File size in bytes.","example":710784},"format":{"type":"string","example":"mp3"},"audio_url":{"type":"string","format":"uri","example":"https://download.quranicaudio.com/qdc/abu_bakr_shatri/murattal/1.mp3"},"timestamps":{"type":"array","description":"Present when timing data is available. If `segments=true`, each item may include a `segments` array.","items":{"type":"object","required":["verse_key","timestamp_from","timestamp_to","duration"],"properties":{"verse_key":{"type":"string","example":"1:1"},"timestamp_from":{"type":"integer","format":"int32","description":"Start offset in milliseconds from the beginning of the file.","example":0},"timestamp_to":{"type":"integer","format":"int32","description":"End offset in milliseconds from the beginning of the file.","example":6493},"duration":{"type":"integer","format":"int32","description":"Duration in milliseconds (mirrors source data; may be negative in legacy data).","example":-6493},"segments":{"type":"array","items":{"type":"array","minItems":3,"maxItems":3,"items":{"type":"integer","format":"int32"},"description":"[word_index, start_ms, end_ms] triplet. word_index is 1-based.","title":"SegmentTriplet"},"description":"Present only when `segments=true`. Word-level timing triplets for the verse.","nullable":true}},"title":"VerseTimestamp"}}},"title":"AudioFile"}},"required":["audio_file"],"title":"ChapterReciterAudioFileResponse"},"examples":{"default_no_segments":{"summary":"segments=false (default)","value":{"audio_file":{"id":457,"chapter_id":1,"file_size":710784,"format":"mp3","audio_url":"https://download.quranicaudio.com/qdc/abu_bakr_shatri/murattal/1.mp3"}}},"with_segments_true":{"summary":"segments=true (includes timestamps + segments)","value":{"audio_file":{"id":457,"chapter_id":1,"file_size":710784,"format":"mp3","audio_url":"https://download.quranicaudio.com/qdc/abu_bakr_shatri/murattal/1.mp3","timestamps":[{"verse_key":"1:1","timestamp_from":0,"timestamp_to":6493,"duration":-6493,"segments":[[1,0,630],[2,650,1570],[3,1570,3110],[4,3110,5590]]},{"verse_key":"1:2","timestamp_from":6493,"timestamp_to":11546,"duration":-5053,"segments":[[1,6493,7243],[2,7243,8123],[3,8143,8723],[4,8723,11193]]},{"verse_key":"1:3","timestamp_from":11546,"timestamp_to":15985,"duration":-4439,"segments":[[1,11546,12806],[2,12916,15366]]},{"verse_key":"1:4","timestamp_from":15985,"timestamp_to":21521,"duration":-5536,"segments":[[1,15985,16505],[2,16705,17235],[3,17265,19155]]},{"verse_key":"1:5","timestamp_from":21521,"timestamp_to":27835,"duration":-6314,"segments":[[1,21521,22591],[2,22591,23471],[3,23631,25001],[4,25001,27391]]},{"verse_key":"1:6","timestamp_from":27835,"timestamp_to":33388,"duration":-5553,"segments":[[1,27835,28265],[2,28265,29405],[3,29405,32545]]},{"verse_key":"1:7","timestamp_from":33388,"timestamp_to":53092,"duration":-19704,"segments":[[1,33388,34338],[2,34338,35448],[3,35518,36698],[4,36718,38678],[5,38678,39608],[6,39628,41638],[7,41638,43778],[8,43778,44218],[9,44338,51818]]}]}}}}}}},"400":{"description":"Will be returned when the request is invalid e.g. request is missing required headers or with invalid query parameters.","content":{"application/json":{"schema":{"title":"invalidRequestResponse","type":"object","properties":{"message":{"type":"string"},"type":{"type":"string","enum":["gateway_timeout","service_unavailable","bad_gateway","internal_server_error","unprocessable_entity","not_found","forbidden","unauthorized","invalid_request","invalid_token","insufficient_scope","service_error","invalid_path","rate_limit_exceeded"]},"success":{"type":"boolean"}}},"example":{"message":"The request is missing required headers or is invalid","type":"invalid_request","success":false}}}},"401":{"description":"Will be returned when the request is unauthorized.","content":{"application/json":{"schema":{"title":"unauthorizedResponse","type":"object","properties":{"message":{"type":"string"},"type":{"type":"string","enum":["gateway_timeout","service_unavailable","bad_gateway","internal_server_error","unprocessable_entity","not_found","forbidden","unauthorized","invalid_request","invalid_token","insufficient_scope","service_error","invalid_path","rate_limit_exceeded"]},"success":{"type":"boolean"}}},"example":{"message":"The request requires user authentication","type":"unauthorized","success":false}}}},"403":{"description":"Forbidden error. Can either be due to access token not being passed, having been expired or the caller trying to access a resource without enough permissions.","content":{"application/json":{"schema":{"title":"forbiddenResponse","type":"object","properties":{"message":{"type":"string"},"type":{"type":"string","enum":["gateway_timeout","service_unavailable","bad_gateway","internal_server_error","unprocessable_entity","not_found","forbidden","unauthorized","invalid_request","invalid_token","insufficient_scope","service_error","invalid_path","rate_limit_exceeded"]},"success":{"type":"boolean"}}},"example":{"message":"The server understood the request, but refuses to authorize it","type":"forbidden","success":false}}}},"404":{"description":"Not Found. The resource being accessed does not exist.","content":{"application/json":{"schema":{"title":"notFoundResponse","type":"object","properties":{"message":{"type":"string"},"type":{"type":"string","enum":["gateway_timeout","service_unavailable","bad_gateway","internal_server_error","unprocessable_entity","not_found","forbidden","unauthorized","invalid_request","invalid_token","insufficient_scope","service_error","invalid_path","rate_limit_exceeded"]},"success":{"type":"boolean"}}},"example":{"message":"The requested resource could not be found","type":"not_found","success":false}}}},"422":{"description":"Validation Error. The request includes one or more invalid params. Please check the request params and try again.","content":{"application/json":{"schema":{"title":"unprocessableEntityResponse","type":"object","properties":{"message":{"type":"string"},"type":{"type":"string","enum":["gateway_timeout","service_unavailable","bad_gateway","internal_server_error","unprocessable_entity","not_found","forbidden","unauthorized","invalid_request","invalid_token","insufficient_scope","service_error","invalid_path","rate_limit_exceeded"]},"success":{"type":"boolean"}}},"example":{"message":"The request was well-formed but was unable to be followed due to semantic errors","type":"unprocessable_entity","success":false}}}},"429":{"description":"Rate-limit exceeded","content":{"application/json":{"schema":{"title":"rateLimitExceededResponse","type":"object","properties":{"message":{"type":"string"},"type":{"type":"string","enum":["gateway_timeout","service_unavailable","bad_gateway","internal_server_error","unprocessable_entity","not_found","forbidden","unauthorized","invalid_request","invalid_token","insufficient_scope","service_error","invalid_path","rate_limit_exceeded"]},"success":{"type":"boolean"}}},"example":{"message":"Too many requests, please try again later","type":"rate_limit_exceeded","success":false}}}},"500":{"description":"Server Error. Something went wrong, try again later.","content":{"application/json":{"schema":{"title":"internalServerErrorResponse","type":"object","properties":{"message":{"type":"string"},"type":{"type":"string","enum":["gateway_timeout","service_unavailable","bad_gateway","internal_server_error","unprocessable_entity","not_found","forbidden","unauthorized","invalid_request","invalid_token","insufficient_scope","service_error","invalid_path","rate_limit_exceeded"]},"success":{"type":"boolean"}}},"example":{"message":"The server encountered an internal error and was unable to complete your request","type":"internal_server_error","success":false}}}},"502":{"description":"Bad Gateway","content":{"application/json":{"schema":{"title":"badGatewayResponse","type":"object","properties":{"message":{"type":"string"},"type":{"type":"string","enum":["gateway_timeout","service_unavailable","bad_gateway","internal_server_error","unprocessable_entity","not_found","forbidden","unauthorized","invalid_request","invalid_token","insufficient_scope","service_error","invalid_path","rate_limit_exceeded"]},"success":{"type":"boolean"}}},"example":{"message":"The server was acting as a gateway or proxy and received an invalid response from the upstream server","type":"bad_gateway","success":false}}}},"503":{"description":"Service Unavailable","content":{"application/json":{"schema":{"title":"serviceUnavailableResponse","type":"object","properties":{"message":{"type":"string"},"type":{"type":"string","enum":["gateway_timeout","service_unavailable","bad_gateway","internal_server_error","unprocessable_entity","not_found","forbidden","unauthorized","invalid_request","invalid_token","insufficient_scope","service_error","invalid_path","rate_limit_exceeded"]},"success":{"type":"boolean"}}},"example":{"message":"The server is currently unable to handle the request due to a temporary overload or scheduled maintenance","type":"service_unavailable","success":false}}}},"504":{"description":"Gateway Timeout","content":{"application/json":{"schema":{"title":"gatewayTimeoutResponse","type":"object","properties":{"message":{"type":"string"},"type":{"type":"string","enum":["gateway_timeout","service_unavailable","bad_gateway","internal_server_error","unprocessable_entity","not_found","forbidden","unauthorized","invalid_request","invalid_token","insufficient_scope","service_error","invalid_path","rate_limit_exceeded"]},"success":{"type":"boolean"}}},"example":{"message":"The server was acting as a gateway or proxy and did not receive a timely response from the upstream server","type":"gateway_timeout","success":false}}}}},"method":"get","path":"/chapter_recitations/{reciter_id}/{chapter_number}","servers":[{"url":"https://apis-prelive.quran.foundation/content/api/v4","description":"Pre-production Server"},{"url":"https://apis.quran.foundation/content/api/v4","description":"Production Server"}],"security":[{"x-auth-token":[],"x-client-id":[]}],"securitySchemes":{"x-auth-token":{"type":"apiKey","description":"The access token required for accessing the endpoints.","name":"x-auth-token","in":"header"},"x-client-id":{"type":"apiKey","description":"Your client Id","name":"x-client-id","in":"header"}},"info":{"title":"Content APIs","description":"Quran.Foundation Content APIs offer programmatic access to the Quran's core content like chapters, verses, recitations, translations, and more, distinct from user-specific data like notes and bookmarks provided by [User-related APIs](/docs/category/user-related-apis).\n\n:::important Integrity of Translations\nPlease **disable any automatic browser-translation features** (e.g. Google-Translate-in-Chrome) when displaying text returned by the *Translations* endpoints. \nRe-translating an already vetted Quranic translation can introduce serious semantic errors.\n:::\n\n ## How to get access \n\n We are using OAuth2 flows to authenticate and authorize requests. To get started, you need to [get an access token](/docs/tutorials/oidc/getting-started-with-oauth2#obtaining-oauth-20-client-credentials) to make requests to our APIs. Since the APIs are not user-related, you will need to use the `client_credentials` grant type and [`content` scope](/docs/user_related_apis_versioned/scopes#content) when sending a request to [The OAuth 2.0 Token Endpoint](/docs/oauth2_apis_versioned/oauth-2-token-exchange) to get the access token. \n\n```mermaid\nsequenceDiagram\n participant App as Your App\n participant Auth as Quran.Foundation
Authorization Server\n participant API as Quran.Foundation
Resources Server\n\n App->>Auth: Request Token with Client Credentials\n Auth-->>App: Token Response (access_token)\n App->>API: Use token to call API\n API-->>App: Requested resource\n\n Note over App,Auth: Access token expires (1 hour)\n\n App->>Auth: Re-issue access_token using client_credentials\n Auth-->>App: New access_token\n```\n\n After getting a valid access token, each request to get resources will have to include 2 headers mentioned below: `x-auth-token` and `x-client-id`. This spec also includes a small subset of Quran Reflect post-read endpoints that are compatible with the `client_credentials` grant. These operations still require `x-auth-token` and `x-client-id`, but they do not use the `content` scope. Use `post.read` for `/quran-reflect/v1/posts/feed`, `/quran-reflect/v1/posts/{id}`, and `/quran-reflect/v1/posts/user-posts/{id}`. Use `comment.read` for `/quran-reflect/v1/posts/{id}/comments` and `/quran-reflect/v1/posts/{id}/all-comments`. These are Quran Reflect gateway endpoints, not `/content/api/v4/...` endpoints.","version":"v4"},"postman":{"name":"Get chapter's audio file of a reciter","description":{"content":"Get chapter's audio file of a reciter. Supports `segments` (boolean query param; default `false`). When `segments=true`, verse-level timestamp entries include `segments` ([word_index, start_ms, end_ms]). All time values are milliseconds.","type":"text/plain"},"url":{"path":["chapter_recitations",":reciter_id",":chapter_number"],"host":["{{baseUrl}}"],"query":[{"disabled":false,"description":{"content":"If true, each verse timestamp includes a `segments` array of [word_index, start_ms, end_ms] triplets. Time values are in milliseconds.","type":"text/plain"},"key":"segments","value":""}],"variable":[{"disabled":false,"description":{"content":"(Required) Chapter-reciter ID from [/resources/chapter_reciters](/docs/content_apis_versioned/chapter-reciters). Do not use ayah-by-ayah recitation IDs from [/resources/recitations](/docs/content_apis_versioned/recitations) here.","type":"text/plain"},"type":"any","value":"","key":"reciter_id"},{"disabled":false,"description":{"content":"(Required) The number of the chapter","type":"text/plain"},"type":"any","value":"","key":"chapter_number"}]},"header":[{"key":"Accept","value":"application/json"}],"method":"GET"}} +api: {"tags":["Audio"],"description":"Get chapter's audio file of a reciter. Supports `segments` (boolean query param; default `false`). When `segments=true`, verse-level timestamp entries include `segments` ([word_index, start_ms, end_ms]). All time values are milliseconds.","operationId":"chapter-reciter-audio-file","parameters":[{"name":"reciter_id","in":"path","description":"Chapter-reciter ID from [/resources/chapter_reciters](/docs/content_apis_versioned/chapter-reciters). Do not use ayah-by-ayah recitation IDs from [/resources/recitations](/docs/content_apis_versioned/recitations) here.","required":true,"schema":{"type":"number"}},{"name":"chapter_number","in":"path","description":"The number of the chapter","required":true,"schema":{"maximum":114,"minimum":1,"type":"number"}},{"name":"segments","in":"query","required":false,"schema":{"type":"boolean","default":false},"description":"If true, each verse timestamp includes a `segments` array of [word_index, start_ms, end_ms] triplets. Time values are in milliseconds."}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"audio_file":{"type":"object","required":["id","chapter_id","file_size","format","audio_url"],"properties":{"id":{"type":"integer","example":457},"chapter_id":{"type":"integer","example":1},"file_size":{"type":"number","format":"float","description":"File size in bytes.","example":710784},"format":{"type":"string","example":"mp3"},"audio_url":{"type":"string","format":"uri","example":"https://download.quranicaudio.com/qdc/abu_bakr_shatri/murattal/1.mp3"},"duration":{"type":"integer","nullable":true,"description":"Length of the audio file in milliseconds. `null` when the length is unknown.","example":53000},"timestamps":{"type":"array","description":"Present when timing data is available. If `segments=true`, each item may include a `segments` array.","items":{"type":"object","required":["verse_key","timestamp_from","timestamp_to","duration"],"properties":{"verse_key":{"type":"string","example":"1:1"},"timestamp_from":{"type":"integer","format":"int32","description":"Start offset in milliseconds from the beginning of the file.","example":0},"timestamp_to":{"type":"integer","format":"int32","description":"End offset in milliseconds from the beginning of the file.","example":6493},"duration":{"type":"integer","format":"int32","description":"Duration in milliseconds (mirrors source data; may be negative in legacy data).","example":-6493},"segments":{"type":"array","items":{"type":"array","minItems":3,"maxItems":3,"items":{"type":"integer","format":"int32"},"description":"[word_index, start_ms, end_ms] triplet. word_index is 1-based.","title":"SegmentTriplet"},"description":"Present only when `segments=true`. Word-level timing triplets for the verse.","nullable":true}},"title":"VerseTimestamp"}}},"title":"AudioFile"}},"required":["audio_file"],"title":"ChapterReciterAudioFileResponse"},"examples":{"default_no_segments":{"summary":"segments=false (default)","value":{"audio_file":{"id":457,"chapter_id":1,"file_size":710784,"format":"mp3","audio_url":"https://download.quranicaudio.com/qdc/abu_bakr_shatri/murattal/1.mp3","duration":53000}}},"with_segments_true":{"summary":"segments=true (includes timestamps + segments)","value":{"audio_file":{"id":457,"chapter_id":1,"file_size":710784,"format":"mp3","audio_url":"https://download.quranicaudio.com/qdc/abu_bakr_shatri/murattal/1.mp3","duration":53000,"timestamps":[{"verse_key":"1:1","timestamp_from":0,"timestamp_to":6493,"duration":-6493,"segments":[[1,0,630],[2,650,1570],[3,1570,3110],[4,3110,5590]]},{"verse_key":"1:2","timestamp_from":6493,"timestamp_to":11546,"duration":-5053,"segments":[[1,6493,7243],[2,7243,8123],[3,8143,8723],[4,8723,11193]]},{"verse_key":"1:3","timestamp_from":11546,"timestamp_to":15985,"duration":-4439,"segments":[[1,11546,12806],[2,12916,15366]]},{"verse_key":"1:4","timestamp_from":15985,"timestamp_to":21521,"duration":-5536,"segments":[[1,15985,16505],[2,16705,17235],[3,17265,19155]]},{"verse_key":"1:5","timestamp_from":21521,"timestamp_to":27835,"duration":-6314,"segments":[[1,21521,22591],[2,22591,23471],[3,23631,25001],[4,25001,27391]]},{"verse_key":"1:6","timestamp_from":27835,"timestamp_to":33388,"duration":-5553,"segments":[[1,27835,28265],[2,28265,29405],[3,29405,32545]]},{"verse_key":"1:7","timestamp_from":33388,"timestamp_to":53092,"duration":-19704,"segments":[[1,33388,34338],[2,34338,35448],[3,35518,36698],[4,36718,38678],[5,38678,39608],[6,39628,41638],[7,41638,43778],[8,43778,44218],[9,44338,51818]]}]}}}}}}},"400":{"description":"Will be returned when the request is invalid e.g. request is missing required headers or with invalid query parameters.","content":{"application/json":{"schema":{"title":"invalidRequestResponse","type":"object","properties":{"message":{"type":"string"},"type":{"type":"string","enum":["gateway_timeout","service_unavailable","bad_gateway","internal_server_error","unprocessable_entity","not_found","forbidden","unauthorized","invalid_request","invalid_token","insufficient_scope","service_error","invalid_path","rate_limit_exceeded"]},"success":{"type":"boolean"}}},"example":{"message":"The request is missing required headers or is invalid","type":"invalid_request","success":false}}}},"401":{"description":"Will be returned when the request is unauthorized.","content":{"application/json":{"schema":{"title":"unauthorizedResponse","type":"object","properties":{"message":{"type":"string"},"type":{"type":"string","enum":["gateway_timeout","service_unavailable","bad_gateway","internal_server_error","unprocessable_entity","not_found","forbidden","unauthorized","invalid_request","invalid_token","insufficient_scope","service_error","invalid_path","rate_limit_exceeded"]},"success":{"type":"boolean"}}},"example":{"message":"The request requires user authentication","type":"unauthorized","success":false}}}},"403":{"description":"The request is forbidden, for example because a valid access token lacks the required scope or the client lacks permission.","content":{"application/json":{"schema":{"title":"forbiddenResponse","type":"object","properties":{"message":{"type":"string"},"type":{"type":"string","enum":["gateway_timeout","service_unavailable","bad_gateway","internal_server_error","unprocessable_entity","not_found","forbidden","unauthorized","invalid_request","invalid_token","insufficient_scope","service_error","invalid_path","rate_limit_exceeded"]},"success":{"type":"boolean"}}},"example":{"message":"The server understood the request, but refuses to authorize it","type":"forbidden","success":false}}}},"404":{"description":"Not Found. The resource being accessed does not exist.","content":{"application/json":{"schema":{"title":"notFoundResponse","type":"object","properties":{"message":{"type":"string"},"type":{"type":"string","enum":["gateway_timeout","service_unavailable","bad_gateway","internal_server_error","unprocessable_entity","not_found","forbidden","unauthorized","invalid_request","invalid_token","insufficient_scope","service_error","invalid_path","rate_limit_exceeded"]},"success":{"type":"boolean"}}},"example":{"message":"The requested resource could not be found","type":"not_found","success":false}}}},"422":{"description":"Validation Error. The request includes one or more invalid params. Please check the request params and try again.","content":{"application/json":{"schema":{"title":"unprocessableEntityResponse","type":"object","properties":{"message":{"type":"string"},"type":{"type":"string","enum":["gateway_timeout","service_unavailable","bad_gateway","internal_server_error","unprocessable_entity","not_found","forbidden","unauthorized","invalid_request","invalid_token","insufficient_scope","service_error","invalid_path","rate_limit_exceeded"]},"success":{"type":"boolean"}}},"example":{"message":"The request was well-formed but was unable to be followed due to semantic errors","type":"unprocessable_entity","success":false}}}},"429":{"description":"Rate-limit exceeded","content":{"application/json":{"schema":{"title":"rateLimitExceededResponse","type":"object","properties":{"message":{"type":"string"},"type":{"type":"string","enum":["gateway_timeout","service_unavailable","bad_gateway","internal_server_error","unprocessable_entity","not_found","forbidden","unauthorized","invalid_request","invalid_token","insufficient_scope","service_error","invalid_path","rate_limit_exceeded"]},"success":{"type":"boolean"}}},"example":{"message":"Too many requests, please try again later","type":"rate_limit_exceeded","success":false}}}},"500":{"description":"Server Error. Something went wrong, try again later.","content":{"application/json":{"schema":{"title":"internalServerErrorResponse","type":"object","properties":{"message":{"type":"string"},"type":{"type":"string","enum":["gateway_timeout","service_unavailable","bad_gateway","internal_server_error","unprocessable_entity","not_found","forbidden","unauthorized","invalid_request","invalid_token","insufficient_scope","service_error","invalid_path","rate_limit_exceeded"]},"success":{"type":"boolean"}}},"example":{"message":"The server encountered an internal error and was unable to complete your request","type":"internal_server_error","success":false}}}},"502":{"description":"Bad Gateway","content":{"application/json":{"schema":{"title":"badGatewayResponse","type":"object","properties":{"message":{"type":"string"},"type":{"type":"string","enum":["gateway_timeout","service_unavailable","bad_gateway","internal_server_error","unprocessable_entity","not_found","forbidden","unauthorized","invalid_request","invalid_token","insufficient_scope","service_error","invalid_path","rate_limit_exceeded"]},"success":{"type":"boolean"}}},"example":{"message":"The server was acting as a gateway or proxy and received an invalid response from the upstream server","type":"bad_gateway","success":false}}}},"503":{"description":"Service Unavailable","content":{"application/json":{"schema":{"title":"serviceUnavailableResponse","type":"object","properties":{"message":{"type":"string"},"type":{"type":"string","enum":["gateway_timeout","service_unavailable","bad_gateway","internal_server_error","unprocessable_entity","not_found","forbidden","unauthorized","invalid_request","invalid_token","insufficient_scope","service_error","invalid_path","rate_limit_exceeded"]},"success":{"type":"boolean"}}},"example":{"message":"The server is currently unable to handle the request due to a temporary overload or scheduled maintenance","type":"service_unavailable","success":false}}}},"504":{"description":"Gateway Timeout","content":{"application/json":{"schema":{"title":"gatewayTimeoutResponse","type":"object","properties":{"message":{"type":"string"},"type":{"type":"string","enum":["gateway_timeout","service_unavailable","bad_gateway","internal_server_error","unprocessable_entity","not_found","forbidden","unauthorized","invalid_request","invalid_token","insufficient_scope","service_error","invalid_path","rate_limit_exceeded"]},"success":{"type":"boolean"}}},"example":{"message":"The server was acting as a gateway or proxy and did not receive a timely response from the upstream server","type":"gateway_timeout","success":false}}}}},"x-qf-scopes":{"contractVersion":"content-scopes/v1","contractSha256":"0bba34fad8ac4ecc6d782eff14ae8f5cf50bac1784c832d5d1eb7d7f8be0ed36","contractStatus":"approved","routeId":"content.v4.chapter-reciter-audio-file","service":"content","anyOf":["content.read","content","content.audio.read"],"legacyAnyOf":["content.read","content"],"granularAnyOf":["content.audio.read"],"deprecatedForNewClients":["content.read","content"],"quotaBuckets":["content.read","content"],"rateLimitPolicyId":"preserve-existing-content-read-policy","responseBoundary":"endpoint-family-not-data-isolation","transport":{"note":"Both headers are required together. These are not OAuth2 bearer credentials.","headers":["x-auth-token","x-client-id"]}},"extensions":[{"key":"x-qf-scopes","value":{"contractVersion":"content-scopes/v1","contractSha256":"0bba34fad8ac4ecc6d782eff14ae8f5cf50bac1784c832d5d1eb7d7f8be0ed36","contractStatus":"approved","routeId":"content.v4.chapter-reciter-audio-file","service":"content","anyOf":["content.read","content","content.audio.read"],"legacyAnyOf":["content.read","content"],"granularAnyOf":["content.audio.read"],"deprecatedForNewClients":["content.read","content"],"quotaBuckets":["content.read","content"],"rateLimitPolicyId":"preserve-existing-content-read-policy","responseBoundary":"endpoint-family-not-data-isolation","transport":{"note":"Both headers are required together. These are not OAuth2 bearer credentials.","headers":["x-auth-token","x-client-id"]}}}],"method":"get","path":"/chapter_recitations/{reciter_id}/{chapter_number}","servers":[{"url":"https://apis-prelive.quran.foundation/content/api/v4","description":"Pre-production Server — testing and development only; Quran content is limited to Al-Fatihah (surah 1) and Al-Baqarah (surah 2)."},{"url":"https://apis.quran.foundation/content/api/v4","description":"Production Server"}],"security":[{"x-auth-token":[],"x-client-id":[]}],"securitySchemes":{"x-auth-token":{"type":"apiKey","description":"The access token required for accessing the endpoints.","name":"x-auth-token","in":"header"},"x-client-id":{"type":"apiKey","description":"Your client Id","name":"x-client-id","in":"header"}},"info":{"title":"Content APIs","description":"Quran Foundation Content APIs offer programmatic access to the Quran's core content like chapters, verses, recitations, translations, and more, distinct from user-specific data like notes and bookmarks provided by [User-related APIs](/docs/category/user-related-apis).\n\n:::note Prelive Content API limitation\nThe prelive environment is for testing and development only. Its Quran content dataset includes only Al-Fatihah (surah 1) and Al-Baqarah (surah 2). Test content requests using these surahs. For the complete Quran dataset, use the production environment after production access is approved.\n:::\n\n:::important Integrity of Translations\nPlease **disable any automatic browser-translation features** (e.g. Google-Translate-in-Chrome) when displaying text returned by the *Translations* endpoints. \nRe-translating an already vetted Quranic translation can introduce serious semantic errors.\n:::\n\n ## How to get access \n\n We are using OAuth2 flows to authenticate and authorize requests. To get started, you need to [get an access token](/docs/tutorials/oidc/getting-started-with-oauth2#obtaining-oauth-20-client-credentials) to make requests to our APIs. Since the APIs are not user-related, you will need to use the `client_credentials` grant type and [`content` scope](/docs/user_related_apis_versioned/scopes#content) when sending a request to [The OAuth 2.0 Token Endpoint](/docs/oauth2_apis_versioned/oauth-2-token-exchange) to get the access token. \n\n```mermaid\nsequenceDiagram\n participant App as Your App\n participant Auth as Quran Foundation
Authorization Server\n participant API as Quran Foundation
Resources Server\n\n App->>Auth: Request Token with Client Credentials\n Auth-->>App: Token Response (access_token)\n App->>API: Use token to call API\n API-->>App: Requested resource\n\n Note over App,Auth: Access token expires (1 hour)\n\n App->>Auth: Re-issue access_token using client_credentials\n Auth-->>App: New access_token\n```\n\n After getting a valid access token, each request to get resources will have to include 2 headers mentioned below: `x-auth-token` and `x-client-id`. This spec also includes a small subset of Quran Reflect post-read endpoints that are compatible with the `client_credentials` grant. These operations still require `x-auth-token` and `x-client-id`, but they do not use the `content` scope. Use `post.read` for `/quran-reflect/v1/posts/feed`, `/quran-reflect/v1/posts/{id}`, and `/quran-reflect/v1/posts/user-posts/{id}`. Use `comment.read` for `/quran-reflect/v1/posts/{id}/comments` and `/quran-reflect/v1/posts/{id}/all-comments`. These are Quran Reflect gateway endpoints, not `/content/api/v4/...` endpoints. The Qira'at endpoints under `/content/api/v4/qiraat/...` are scope-gated: they require the `qiraat.read` scope (or the parent `qiraat` scope) instead of `content`, so request the Qira'at scope your client has been approved for when you [get an access token](/docs/user_related_apis_versioned/scopes#qiraat).","version":"v4"},"postman":{"name":"Get chapter's audio file of a reciter","description":{"content":"Get chapter's audio file of a reciter. Supports `segments` (boolean query param; default `false`). When `segments=true`, verse-level timestamp entries include `segments` ([word_index, start_ms, end_ms]). All time values are milliseconds.","type":"text/plain"},"url":{"path":["chapter_recitations",":reciter_id",":chapter_number"],"host":["{{baseUrl}}"],"query":[{"disabled":false,"description":{"content":"If true, each verse timestamp includes a `segments` array of [word_index, start_ms, end_ms] triplets. Time values are in milliseconds.","type":"text/plain"},"key":"segments","value":""}],"variable":[{"disabled":false,"description":{"content":"(Required) Chapter-reciter ID from [/resources/chapter_reciters](/docs/content_apis_versioned/chapter-reciters). Do not use ayah-by-ayah recitation IDs from [/resources/recitations](/docs/content_apis_versioned/recitations) here.","type":"text/plain"},"type":"any","value":"","key":"reciter_id"},{"disabled":false,"description":{"content":"(Required) The number of the chapter","type":"text/plain"},"type":"any","value":"","key":"chapter_number"}]},"header":[{"key":"Accept","value":"application/json"}],"method":"GET"}} sidebar_class_name: "get api-method" info_path: docs/content_apis_versioned/content-apis custom_edit_url: null @@ -31,11 +31,11 @@ Get chapter's audio file of a reciter. Supports `segments` (boolean query param; Successful response -
Schema
    audio_file object required
    timestamps object[]
    +
    Schema
      audio_file object required
      timestamps object[]
      Present when timing data is available. If `segments=true`, each item may include a `segments` array. -
    • Array [
    • = 3`, `<= 3`"} schema={{"type":"array","items":{"type":"array","minItems":3,"maxItems":3,"items":{"type":"integer","format":"int32"},"description":"[word_index, start_ms, end_ms] triplet. word_index is 1-based.","title":"SegmentTriplet"},"description":"Present only when `segments=true`. Word-level timing triplets for the verse.","nullable":true}}>
    • ]

    segments=false (default)

    segments=true (includes timestamps + segments)

    +
  • Array [
  • = 3`, `<= 3`"} schema={{"type":"array","items":{"type":"array","minItems":3,"maxItems":3,"items":{"type":"integer","format":"int32"},"description":"[word_index, start_ms, end_ms] triplet. word_index is 1-based.","title":"SegmentTriplet"},"description":"Present only when `segments=true`. Word-level timing triplets for the verse.","nullable":true}}>
  • ]

segments=false (default)

segments=true (includes timestamps + segments)

Will be returned when the request is invalid e.g. request is missing required headers or with invalid query parameters. @@ -45,7 +45,7 @@ Will be returned when the request is unauthorized.
Schema
-Forbidden error. Can either be due to access token not being passed, having been expired or the caller trying to access a resource without enough permissions. +The request is forbidden, for example because a valid access token lacks the required scope or the client lacks permission.
Schema
diff --git a/docs/content_apis_versioned/chapter-reciter-audio-files.api.mdx b/docs/content_apis_versioned/chapter-reciter-audio-files.api.mdx index 9e0c4ba1..2aee2526 100644 --- a/docs/content_apis_versioned/chapter-reciter-audio-files.api.mdx +++ b/docs/content_apis_versioned/chapter-reciter-audio-files.api.mdx @@ -5,7 +5,7 @@ description: "Get list of chapters' audio files of a reciter." sidebar_label: "List of all chapter audio files of a reciter" hide_title: true hide_table_of_contents: true -api: {"tags":["Audio"],"description":"Get list of chapters' audio files of a reciter.","operationId":"chapter-reciter-audio-files","parameters":[{"name":"reciter_id","in":"path","description":"Chapter-reciter ID from [/resources/chapter_reciters](/docs/content_apis_versioned/chapter-reciters). Do not use ayah-by-ayah recitation IDs from [/resources/recitations](/docs/content_apis_versioned/recitations) here.","required":true,"schema":{"type":"number"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"required":["audio_files"],"type":"object","properties":{"audio_files":{"type":"array","items":{"title":"Chapter Recitation","type":"object","properties":{"id":{"type":"integer","description":"The Id of the audio file"},"chapter_id":{"type":"integer","description":"The chapter id"},"file_size":{"type":"integer","description":"The file size in bytes"},"format":{"type":"string","description":"The format of the file"},"audio_url":{"type":"string","description":"The audio file's url"}},"example":{"id":1,"chapter_id":1,"file_size":710784,"format":"mp3","audio_url":"https://download.quranicaudio.com/quran/abdullaah_3awwaad_al-juhaynee//001.mp3"},"required":["id","chapter_id","file_size","format","audio_url"]}}}},"examples":{"default_success":{"summary":"Successful response","value":{"audio_files":[{"id":43,"chapter_id":22,"file_size":19779712,"format":"mp3","audio_url":"https://download.quranicaudio.com/quran/abdullaah_3awwaad_al-juhaynee//022.mp3"},{"id":87,"chapter_id":44,"file_size":6453376,"format":"mp3","audio_url":"https://download.quranicaudio.com/quran/abdullaah_3awwaad_al-juhaynee//044.mp3"}]}},"available_chapter_files":{"summary":"Chapter-level audio files for a reciter","value":{"audio_files":[{"id":43,"chapter_id":22,"file_size":19779712,"format":"mp3","audio_url":"https://download.quranicaudio.com/quran/abdullaah_3awwaad_al-juhaynee/022.mp3"},{"id":87,"chapter_id":44,"file_size":6453376,"format":"mp3","audio_url":"https://download.quranicaudio.com/quran/abdullaah_3awwaad_al-juhaynee/044.mp3"}]}}}}}},"400":{"description":"Will be returned when the request is invalid e.g. request is missing required headers or with invalid query parameters.","content":{"application/json":{"schema":{"title":"invalidRequestResponse","type":"object","properties":{"message":{"type":"string"},"type":{"type":"string","enum":["gateway_timeout","service_unavailable","bad_gateway","internal_server_error","unprocessable_entity","not_found","forbidden","unauthorized","invalid_request","invalid_token","insufficient_scope","service_error","invalid_path","rate_limit_exceeded"]},"success":{"type":"boolean"}}},"example":{"message":"The request is missing required headers or is invalid","type":"invalid_request","success":false}}}},"401":{"description":"Will be returned when the request is unauthorized.","content":{"application/json":{"schema":{"title":"unauthorizedResponse","type":"object","properties":{"message":{"type":"string"},"type":{"type":"string","enum":["gateway_timeout","service_unavailable","bad_gateway","internal_server_error","unprocessable_entity","not_found","forbidden","unauthorized","invalid_request","invalid_token","insufficient_scope","service_error","invalid_path","rate_limit_exceeded"]},"success":{"type":"boolean"}}},"example":{"message":"The request requires user authentication","type":"unauthorized","success":false}}}},"403":{"description":"Forbidden error. Can either be due to access token not being passed, having been expired or the caller trying to access a resource without enough permissions.","content":{"application/json":{"schema":{"title":"forbiddenResponse","type":"object","properties":{"message":{"type":"string"},"type":{"type":"string","enum":["gateway_timeout","service_unavailable","bad_gateway","internal_server_error","unprocessable_entity","not_found","forbidden","unauthorized","invalid_request","invalid_token","insufficient_scope","service_error","invalid_path","rate_limit_exceeded"]},"success":{"type":"boolean"}}},"example":{"message":"The server understood the request, but refuses to authorize it","type":"forbidden","success":false}}}},"404":{"description":"Not Found. The resource being accessed does not exist.","content":{"application/json":{"schema":{"title":"notFoundResponse","type":"object","properties":{"message":{"type":"string"},"type":{"type":"string","enum":["gateway_timeout","service_unavailable","bad_gateway","internal_server_error","unprocessable_entity","not_found","forbidden","unauthorized","invalid_request","invalid_token","insufficient_scope","service_error","invalid_path","rate_limit_exceeded"]},"success":{"type":"boolean"}}},"example":{"message":"The requested resource could not be found","type":"not_found","success":false}}}},"422":{"description":"Validation Error. The request includes one or more invalid params. Please check the request params and try again.","content":{"application/json":{"schema":{"title":"unprocessableEntityResponse","type":"object","properties":{"message":{"type":"string"},"type":{"type":"string","enum":["gateway_timeout","service_unavailable","bad_gateway","internal_server_error","unprocessable_entity","not_found","forbidden","unauthorized","invalid_request","invalid_token","insufficient_scope","service_error","invalid_path","rate_limit_exceeded"]},"success":{"type":"boolean"}}},"example":{"message":"The request was well-formed but was unable to be followed due to semantic errors","type":"unprocessable_entity","success":false}}}},"429":{"description":"Rate-limit exceeded","content":{"application/json":{"schema":{"title":"rateLimitExceededResponse","type":"object","properties":{"message":{"type":"string"},"type":{"type":"string","enum":["gateway_timeout","service_unavailable","bad_gateway","internal_server_error","unprocessable_entity","not_found","forbidden","unauthorized","invalid_request","invalid_token","insufficient_scope","service_error","invalid_path","rate_limit_exceeded"]},"success":{"type":"boolean"}}},"example":{"message":"Too many requests, please try again later","type":"rate_limit_exceeded","success":false}}}},"500":{"description":"Server Error. Something went wrong, try again later.","content":{"application/json":{"schema":{"title":"internalServerErrorResponse","type":"object","properties":{"message":{"type":"string"},"type":{"type":"string","enum":["gateway_timeout","service_unavailable","bad_gateway","internal_server_error","unprocessable_entity","not_found","forbidden","unauthorized","invalid_request","invalid_token","insufficient_scope","service_error","invalid_path","rate_limit_exceeded"]},"success":{"type":"boolean"}}},"example":{"message":"The server encountered an internal error and was unable to complete your request","type":"internal_server_error","success":false}}}},"502":{"description":"Bad Gateway","content":{"application/json":{"schema":{"title":"badGatewayResponse","type":"object","properties":{"message":{"type":"string"},"type":{"type":"string","enum":["gateway_timeout","service_unavailable","bad_gateway","internal_server_error","unprocessable_entity","not_found","forbidden","unauthorized","invalid_request","invalid_token","insufficient_scope","service_error","invalid_path","rate_limit_exceeded"]},"success":{"type":"boolean"}}},"example":{"message":"The server was acting as a gateway or proxy and received an invalid response from the upstream server","type":"bad_gateway","success":false}}}},"503":{"description":"Service Unavailable","content":{"application/json":{"schema":{"title":"serviceUnavailableResponse","type":"object","properties":{"message":{"type":"string"},"type":{"type":"string","enum":["gateway_timeout","service_unavailable","bad_gateway","internal_server_error","unprocessable_entity","not_found","forbidden","unauthorized","invalid_request","invalid_token","insufficient_scope","service_error","invalid_path","rate_limit_exceeded"]},"success":{"type":"boolean"}}},"example":{"message":"The server is currently unable to handle the request due to a temporary overload or scheduled maintenance","type":"service_unavailable","success":false}}}},"504":{"description":"Gateway Timeout","content":{"application/json":{"schema":{"title":"gatewayTimeoutResponse","type":"object","properties":{"message":{"type":"string"},"type":{"type":"string","enum":["gateway_timeout","service_unavailable","bad_gateway","internal_server_error","unprocessable_entity","not_found","forbidden","unauthorized","invalid_request","invalid_token","insufficient_scope","service_error","invalid_path","rate_limit_exceeded"]},"success":{"type":"boolean"}}},"example":{"message":"The server was acting as a gateway or proxy and did not receive a timely response from the upstream server","type":"gateway_timeout","success":false}}}}},"method":"get","path":"/chapter_recitations/{reciter_id}","servers":[{"url":"https://apis-prelive.quran.foundation/content/api/v4","description":"Pre-production Server"},{"url":"https://apis.quran.foundation/content/api/v4","description":"Production Server"}],"security":[{"x-auth-token":[],"x-client-id":[]}],"securitySchemes":{"x-auth-token":{"type":"apiKey","description":"The access token required for accessing the endpoints.","name":"x-auth-token","in":"header"},"x-client-id":{"type":"apiKey","description":"Your client Id","name":"x-client-id","in":"header"}},"info":{"title":"Content APIs","description":"Quran.Foundation Content APIs offer programmatic access to the Quran's core content like chapters, verses, recitations, translations, and more, distinct from user-specific data like notes and bookmarks provided by [User-related APIs](/docs/category/user-related-apis).\n\n:::important Integrity of Translations\nPlease **disable any automatic browser-translation features** (e.g. Google-Translate-in-Chrome) when displaying text returned by the *Translations* endpoints. \nRe-translating an already vetted Quranic translation can introduce serious semantic errors.\n:::\n\n ## How to get access \n\n We are using OAuth2 flows to authenticate and authorize requests. To get started, you need to [get an access token](/docs/tutorials/oidc/getting-started-with-oauth2#obtaining-oauth-20-client-credentials) to make requests to our APIs. Since the APIs are not user-related, you will need to use the `client_credentials` grant type and [`content` scope](/docs/user_related_apis_versioned/scopes#content) when sending a request to [The OAuth 2.0 Token Endpoint](/docs/oauth2_apis_versioned/oauth-2-token-exchange) to get the access token. \n\n```mermaid\nsequenceDiagram\n participant App as Your App\n participant Auth as Quran.Foundation
Authorization Server\n participant API as Quran.Foundation
Resources Server\n\n App->>Auth: Request Token with Client Credentials\n Auth-->>App: Token Response (access_token)\n App->>API: Use token to call API\n API-->>App: Requested resource\n\n Note over App,Auth: Access token expires (1 hour)\n\n App->>Auth: Re-issue access_token using client_credentials\n Auth-->>App: New access_token\n```\n\n After getting a valid access token, each request to get resources will have to include 2 headers mentioned below: `x-auth-token` and `x-client-id`. This spec also includes a small subset of Quran Reflect post-read endpoints that are compatible with the `client_credentials` grant. These operations still require `x-auth-token` and `x-client-id`, but they do not use the `content` scope. Use `post.read` for `/quran-reflect/v1/posts/feed`, `/quran-reflect/v1/posts/{id}`, and `/quran-reflect/v1/posts/user-posts/{id}`. Use `comment.read` for `/quran-reflect/v1/posts/{id}/comments` and `/quran-reflect/v1/posts/{id}/all-comments`. These are Quran Reflect gateway endpoints, not `/content/api/v4/...` endpoints.","version":"v4"},"postman":{"name":"List of all chapter audio files of a reciter","description":{"content":"Get list of chapters' audio files of a reciter.","type":"text/plain"},"url":{"path":["chapter_recitations",":reciter_id"],"host":["{{baseUrl}}"],"query":[],"variable":[{"disabled":false,"description":{"content":"(Required) Chapter-reciter ID from [/resources/chapter_reciters](/docs/content_apis_versioned/chapter-reciters). Do not use ayah-by-ayah recitation IDs from [/resources/recitations](/docs/content_apis_versioned/recitations) here.","type":"text/plain"},"type":"any","value":"","key":"reciter_id"}]},"header":[{"key":"Accept","value":"application/json"}],"method":"GET"}} +api: {"tags":["Audio"],"description":"Get list of chapters' audio files of a reciter.","operationId":"chapter-reciter-audio-files","parameters":[{"name":"reciter_id","in":"path","description":"Chapter-reciter ID from [/resources/chapter_reciters](/docs/content_apis_versioned/chapter-reciters). Do not use ayah-by-ayah recitation IDs from [/resources/recitations](/docs/content_apis_versioned/recitations) here.","required":true,"schema":{"type":"number"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"required":["audio_files"],"type":"object","properties":{"audio_files":{"type":"array","items":{"title":"Chapter Recitation","type":"object","properties":{"id":{"type":"integer","description":"The Id of the audio file"},"chapter_id":{"type":"integer","description":"The chapter id"},"file_size":{"type":"integer","description":"The file size in bytes"},"format":{"type":"string","description":"The format of the file"},"audio_url":{"type":"string","description":"The audio file's url"},"duration":{"type":"integer","nullable":true,"description":"Length of the audio file in milliseconds. `null` when the length is unknown."}},"example":{"id":1,"chapter_id":1,"file_size":710784,"format":"mp3","audio_url":"https://download.quranicaudio.com/quran/abdullaah_3awwaad_al-juhaynee//001.mp3"},"required":["id","chapter_id","file_size","format","audio_url"]}}}},"examples":{"default_success":{"summary":"Successful response","value":{"audio_files":[{"id":43,"chapter_id":22,"file_size":19779712,"format":"mp3","audio_url":"https://download.quranicaudio.com/quran/abdullaah_3awwaad_al-juhaynee//022.mp3"},{"id":87,"chapter_id":44,"file_size":6453376,"format":"mp3","audio_url":"https://download.quranicaudio.com/quran/abdullaah_3awwaad_al-juhaynee//044.mp3"}]}},"available_chapter_files":{"summary":"Chapter-level audio files for a reciter","value":{"audio_files":[{"id":43,"chapter_id":22,"file_size":19779712,"format":"mp3","audio_url":"https://download.quranicaudio.com/quran/abdullaah_3awwaad_al-juhaynee/022.mp3"},{"id":87,"chapter_id":44,"file_size":6453376,"format":"mp3","audio_url":"https://download.quranicaudio.com/quran/abdullaah_3awwaad_al-juhaynee/044.mp3"}]}}}}}},"400":{"description":"Will be returned when the request is invalid e.g. request is missing required headers or with invalid query parameters.","content":{"application/json":{"schema":{"title":"invalidRequestResponse","type":"object","properties":{"message":{"type":"string"},"type":{"type":"string","enum":["gateway_timeout","service_unavailable","bad_gateway","internal_server_error","unprocessable_entity","not_found","forbidden","unauthorized","invalid_request","invalid_token","insufficient_scope","service_error","invalid_path","rate_limit_exceeded"]},"success":{"type":"boolean"}}},"example":{"message":"The request is missing required headers or is invalid","type":"invalid_request","success":false}}}},"401":{"description":"Will be returned when the request is unauthorized.","content":{"application/json":{"schema":{"title":"unauthorizedResponse","type":"object","properties":{"message":{"type":"string"},"type":{"type":"string","enum":["gateway_timeout","service_unavailable","bad_gateway","internal_server_error","unprocessable_entity","not_found","forbidden","unauthorized","invalid_request","invalid_token","insufficient_scope","service_error","invalid_path","rate_limit_exceeded"]},"success":{"type":"boolean"}}},"example":{"message":"The request requires user authentication","type":"unauthorized","success":false}}}},"403":{"description":"The request is forbidden, for example because a valid access token lacks the required scope or the client lacks permission.","content":{"application/json":{"schema":{"title":"forbiddenResponse","type":"object","properties":{"message":{"type":"string"},"type":{"type":"string","enum":["gateway_timeout","service_unavailable","bad_gateway","internal_server_error","unprocessable_entity","not_found","forbidden","unauthorized","invalid_request","invalid_token","insufficient_scope","service_error","invalid_path","rate_limit_exceeded"]},"success":{"type":"boolean"}}},"example":{"message":"The server understood the request, but refuses to authorize it","type":"forbidden","success":false}}}},"404":{"description":"Not Found. The resource being accessed does not exist.","content":{"application/json":{"schema":{"title":"notFoundResponse","type":"object","properties":{"message":{"type":"string"},"type":{"type":"string","enum":["gateway_timeout","service_unavailable","bad_gateway","internal_server_error","unprocessable_entity","not_found","forbidden","unauthorized","invalid_request","invalid_token","insufficient_scope","service_error","invalid_path","rate_limit_exceeded"]},"success":{"type":"boolean"}}},"example":{"message":"The requested resource could not be found","type":"not_found","success":false}}}},"422":{"description":"Validation Error. The request includes one or more invalid params. Please check the request params and try again.","content":{"application/json":{"schema":{"title":"unprocessableEntityResponse","type":"object","properties":{"message":{"type":"string"},"type":{"type":"string","enum":["gateway_timeout","service_unavailable","bad_gateway","internal_server_error","unprocessable_entity","not_found","forbidden","unauthorized","invalid_request","invalid_token","insufficient_scope","service_error","invalid_path","rate_limit_exceeded"]},"success":{"type":"boolean"}}},"example":{"message":"The request was well-formed but was unable to be followed due to semantic errors","type":"unprocessable_entity","success":false}}}},"429":{"description":"Rate-limit exceeded","content":{"application/json":{"schema":{"title":"rateLimitExceededResponse","type":"object","properties":{"message":{"type":"string"},"type":{"type":"string","enum":["gateway_timeout","service_unavailable","bad_gateway","internal_server_error","unprocessable_entity","not_found","forbidden","unauthorized","invalid_request","invalid_token","insufficient_scope","service_error","invalid_path","rate_limit_exceeded"]},"success":{"type":"boolean"}}},"example":{"message":"Too many requests, please try again later","type":"rate_limit_exceeded","success":false}}}},"500":{"description":"Server Error. Something went wrong, try again later.","content":{"application/json":{"schema":{"title":"internalServerErrorResponse","type":"object","properties":{"message":{"type":"string"},"type":{"type":"string","enum":["gateway_timeout","service_unavailable","bad_gateway","internal_server_error","unprocessable_entity","not_found","forbidden","unauthorized","invalid_request","invalid_token","insufficient_scope","service_error","invalid_path","rate_limit_exceeded"]},"success":{"type":"boolean"}}},"example":{"message":"The server encountered an internal error and was unable to complete your request","type":"internal_server_error","success":false}}}},"502":{"description":"Bad Gateway","content":{"application/json":{"schema":{"title":"badGatewayResponse","type":"object","properties":{"message":{"type":"string"},"type":{"type":"string","enum":["gateway_timeout","service_unavailable","bad_gateway","internal_server_error","unprocessable_entity","not_found","forbidden","unauthorized","invalid_request","invalid_token","insufficient_scope","service_error","invalid_path","rate_limit_exceeded"]},"success":{"type":"boolean"}}},"example":{"message":"The server was acting as a gateway or proxy and received an invalid response from the upstream server","type":"bad_gateway","success":false}}}},"503":{"description":"Service Unavailable","content":{"application/json":{"schema":{"title":"serviceUnavailableResponse","type":"object","properties":{"message":{"type":"string"},"type":{"type":"string","enum":["gateway_timeout","service_unavailable","bad_gateway","internal_server_error","unprocessable_entity","not_found","forbidden","unauthorized","invalid_request","invalid_token","insufficient_scope","service_error","invalid_path","rate_limit_exceeded"]},"success":{"type":"boolean"}}},"example":{"message":"The server is currently unable to handle the request due to a temporary overload or scheduled maintenance","type":"service_unavailable","success":false}}}},"504":{"description":"Gateway Timeout","content":{"application/json":{"schema":{"title":"gatewayTimeoutResponse","type":"object","properties":{"message":{"type":"string"},"type":{"type":"string","enum":["gateway_timeout","service_unavailable","bad_gateway","internal_server_error","unprocessable_entity","not_found","forbidden","unauthorized","invalid_request","invalid_token","insufficient_scope","service_error","invalid_path","rate_limit_exceeded"]},"success":{"type":"boolean"}}},"example":{"message":"The server was acting as a gateway or proxy and did not receive a timely response from the upstream server","type":"gateway_timeout","success":false}}}}},"x-qf-scopes":{"contractVersion":"content-scopes/v1","contractSha256":"0bba34fad8ac4ecc6d782eff14ae8f5cf50bac1784c832d5d1eb7d7f8be0ed36","contractStatus":"approved","routeId":"content.v4.chapter-reciter-audio-files","service":"content","anyOf":["content.read","content","content.audio.read"],"legacyAnyOf":["content.read","content"],"granularAnyOf":["content.audio.read"],"deprecatedForNewClients":["content.read","content"],"quotaBuckets":["content.read","content"],"rateLimitPolicyId":"preserve-existing-content-read-policy","responseBoundary":"endpoint-family-not-data-isolation","transport":{"note":"Both headers are required together. These are not OAuth2 bearer credentials.","headers":["x-auth-token","x-client-id"]}},"extensions":[{"key":"x-qf-scopes","value":{"contractVersion":"content-scopes/v1","contractSha256":"0bba34fad8ac4ecc6d782eff14ae8f5cf50bac1784c832d5d1eb7d7f8be0ed36","contractStatus":"approved","routeId":"content.v4.chapter-reciter-audio-files","service":"content","anyOf":["content.read","content","content.audio.read"],"legacyAnyOf":["content.read","content"],"granularAnyOf":["content.audio.read"],"deprecatedForNewClients":["content.read","content"],"quotaBuckets":["content.read","content"],"rateLimitPolicyId":"preserve-existing-content-read-policy","responseBoundary":"endpoint-family-not-data-isolation","transport":{"note":"Both headers are required together. These are not OAuth2 bearer credentials.","headers":["x-auth-token","x-client-id"]}}}],"method":"get","path":"/chapter_recitations/{reciter_id}","servers":[{"url":"https://apis-prelive.quran.foundation/content/api/v4","description":"Pre-production Server — testing and development only; Quran content is limited to Al-Fatihah (surah 1) and Al-Baqarah (surah 2)."},{"url":"https://apis.quran.foundation/content/api/v4","description":"Production Server"}],"security":[{"x-auth-token":[],"x-client-id":[]}],"securitySchemes":{"x-auth-token":{"type":"apiKey","description":"The access token required for accessing the endpoints.","name":"x-auth-token","in":"header"},"x-client-id":{"type":"apiKey","description":"Your client Id","name":"x-client-id","in":"header"}},"info":{"title":"Content APIs","description":"Quran Foundation Content APIs offer programmatic access to the Quran's core content like chapters, verses, recitations, translations, and more, distinct from user-specific data like notes and bookmarks provided by [User-related APIs](/docs/category/user-related-apis).\n\n:::note Prelive Content API limitation\nThe prelive environment is for testing and development only. Its Quran content dataset includes only Al-Fatihah (surah 1) and Al-Baqarah (surah 2). Test content requests using these surahs. For the complete Quran dataset, use the production environment after production access is approved.\n:::\n\n:::important Integrity of Translations\nPlease **disable any automatic browser-translation features** (e.g. Google-Translate-in-Chrome) when displaying text returned by the *Translations* endpoints. \nRe-translating an already vetted Quranic translation can introduce serious semantic errors.\n:::\n\n ## How to get access \n\n We are using OAuth2 flows to authenticate and authorize requests. To get started, you need to [get an access token](/docs/tutorials/oidc/getting-started-with-oauth2#obtaining-oauth-20-client-credentials) to make requests to our APIs. Since the APIs are not user-related, you will need to use the `client_credentials` grant type and [`content` scope](/docs/user_related_apis_versioned/scopes#content) when sending a request to [The OAuth 2.0 Token Endpoint](/docs/oauth2_apis_versioned/oauth-2-token-exchange) to get the access token. \n\n```mermaid\nsequenceDiagram\n participant App as Your App\n participant Auth as Quran Foundation
Authorization Server\n participant API as Quran Foundation
Resources Server\n\n App->>Auth: Request Token with Client Credentials\n Auth-->>App: Token Response (access_token)\n App->>API: Use token to call API\n API-->>App: Requested resource\n\n Note over App,Auth: Access token expires (1 hour)\n\n App->>Auth: Re-issue access_token using client_credentials\n Auth-->>App: New access_token\n```\n\n After getting a valid access token, each request to get resources will have to include 2 headers mentioned below: `x-auth-token` and `x-client-id`. This spec also includes a small subset of Quran Reflect post-read endpoints that are compatible with the `client_credentials` grant. These operations still require `x-auth-token` and `x-client-id`, but they do not use the `content` scope. Use `post.read` for `/quran-reflect/v1/posts/feed`, `/quran-reflect/v1/posts/{id}`, and `/quran-reflect/v1/posts/user-posts/{id}`. Use `comment.read` for `/quran-reflect/v1/posts/{id}/comments` and `/quran-reflect/v1/posts/{id}/all-comments`. These are Quran Reflect gateway endpoints, not `/content/api/v4/...` endpoints. The Qira'at endpoints under `/content/api/v4/qiraat/...` are scope-gated: they require the `qiraat.read` scope (or the parent `qiraat` scope) instead of `content`, so request the Qira'at scope your client has been approved for when you [get an access token](/docs/user_related_apis_versioned/scopes#qiraat).","version":"v4"},"postman":{"name":"List of all chapter audio files of a reciter","description":{"content":"Get list of chapters' audio files of a reciter.","type":"text/plain"},"url":{"path":["chapter_recitations",":reciter_id"],"host":["{{baseUrl}}"],"query":[],"variable":[{"disabled":false,"description":{"content":"(Required) Chapter-reciter ID from [/resources/chapter_reciters](/docs/content_apis_versioned/chapter-reciters). Do not use ayah-by-ayah recitation IDs from [/resources/recitations](/docs/content_apis_versioned/recitations) here.","type":"text/plain"},"type":"any","value":"","key":"reciter_id"}]},"header":[{"key":"Accept","value":"application/json"}],"method":"GET"}} sidebar_class_name: "get api-method" info_path: docs/content_apis_versioned/content-apis custom_edit_url: null @@ -31,7 +31,7 @@ Get list of chapters' audio files of a reciter. Successful response -
Schema
    audio_files object[] required
  • Array [
  • ]

Successful response

Chapter-level audio files for a reciter

+
Schema
    audio_files object[] required
  • Array [
  • ]

Successful response

Chapter-level audio files for a reciter

Will be returned when the request is invalid e.g. request is missing required headers or with invalid query parameters. @@ -41,7 +41,7 @@ Will be returned when the request is unauthorized.
Schema
-Forbidden error. Can either be due to access token not being passed, having been expired or the caller trying to access a resource without enough permissions. +The request is forbidden, for example because a valid access token lacks the required scope or the client lacks permission.
Schema
diff --git a/docs/content_apis_versioned/chapter-reciters.api.mdx b/docs/content_apis_versioned/chapter-reciters.api.mdx index 89738d8d..43bad08c 100644 --- a/docs/content_apis_versioned/chapter-reciters.api.mdx +++ b/docs/content_apis_versioned/chapter-reciters.api.mdx @@ -5,7 +5,7 @@ description: "Get list of available chapter reciters. Use these IDs with `/chapt sidebar_label: "List of Chapter Reciters" hide_title: true hide_table_of_contents: true -api: {"tags":["Audio"],"description":"Get list of available chapter reciters. Use these IDs with `/chapter_recitations/{reciter_id}`, `/chapter_recitations/{reciter_id}/{chapter_number}`, `/audio/reciters/{reciter_id}/timestamp`, and `/audio/reciters/{reciter_id}/lookup`. These IDs are not interchangeable with ayah-by-ayah recitation IDs from `/resources/recitations`.","operationId":"chapter-reciters","parameters":[{"name":"language","in":"query","description":"Name of reciters in specific language. Will fallback to English if we don't have names in specific language.","schema":{"type":"string","default":"en"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","required":["reciters"],"properties":{"reciters":{"type":"array","items":{"title":"Chapter Reciters","required":["id","name","style","qirat"],"type":"object","properties":{"id":{"type":"integer","description":"Reciter ID"},"name":{"type":"string","description":"Name of reciter in English"},"style":{"type":"object","properties":{"name":{"type":"string","nullable":true},"language_name":{"type":"string"}},"required":["language_name"]},"qirat":{"type":"object","properties":{"name":{"type":"string","nullable":true},"language_name":{"type":"string"}},"required":["language_name"]},"translated_name":{"nullable":true,"allOf":[{"title":"TranslatedName","required":["language_name","name"],"type":"object","properties":{"language_name":{"type":"string","default":"english"},"name":{"type":"string","description":"Name of the resource in specific language."}},"example":{"language_name":"english","name":"The Opener"}}]}},"example":{"id":3,"name":"Abu Bakr al-Shatri","style":{"name":"Murattal","language_name":"english"},"qirat":{"name":"Hafs","language_name":"english"},"translated_name":{"name":"Abu Bakr al-Shatri","language_name":"english"}}}}}},"examples":{"default_success":{"summary":"Successful response","value":{"reciters":[{"id":3,"name":"Abu Bakr al-Shatri","style":{"name":"Murattal","language_name":"english"},"qirat":{"name":"Hafs","language_name":"english"},"translated_name":{"name":"Abu Bakr al-Shatri","language_name":"english"}}]}}}}}},"400":{"description":"Will be returned when the request is invalid e.g. request is missing required headers or with invalid query parameters.","content":{"application/json":{"schema":{"title":"invalidRequestResponse","type":"object","properties":{"message":{"type":"string"},"type":{"type":"string","enum":["gateway_timeout","service_unavailable","bad_gateway","internal_server_error","unprocessable_entity","not_found","forbidden","unauthorized","invalid_request","invalid_token","insufficient_scope","service_error","invalid_path","rate_limit_exceeded"]},"success":{"type":"boolean"}}},"example":{"message":"The request is missing required headers or is invalid","type":"invalid_request","success":false}}}},"401":{"description":"Will be returned when the request is unauthorized.","content":{"application/json":{"schema":{"title":"unauthorizedResponse","type":"object","properties":{"message":{"type":"string"},"type":{"type":"string","enum":["gateway_timeout","service_unavailable","bad_gateway","internal_server_error","unprocessable_entity","not_found","forbidden","unauthorized","invalid_request","invalid_token","insufficient_scope","service_error","invalid_path","rate_limit_exceeded"]},"success":{"type":"boolean"}}},"example":{"message":"The request requires user authentication","type":"unauthorized","success":false}}}},"403":{"description":"Forbidden error. Can either be due to access token not being passed, having been expired or the caller trying to access a resource without enough permissions.","content":{"application/json":{"schema":{"title":"forbiddenResponse","type":"object","properties":{"message":{"type":"string"},"type":{"type":"string","enum":["gateway_timeout","service_unavailable","bad_gateway","internal_server_error","unprocessable_entity","not_found","forbidden","unauthorized","invalid_request","invalid_token","insufficient_scope","service_error","invalid_path","rate_limit_exceeded"]},"success":{"type":"boolean"}}},"example":{"message":"The server understood the request, but refuses to authorize it","type":"forbidden","success":false}}}},"404":{"description":"Not Found. The resource being accessed does not exist.","content":{"application/json":{"schema":{"title":"notFoundResponse","type":"object","properties":{"message":{"type":"string"},"type":{"type":"string","enum":["gateway_timeout","service_unavailable","bad_gateway","internal_server_error","unprocessable_entity","not_found","forbidden","unauthorized","invalid_request","invalid_token","insufficient_scope","service_error","invalid_path","rate_limit_exceeded"]},"success":{"type":"boolean"}}},"example":{"message":"The requested resource could not be found","type":"not_found","success":false}}}},"422":{"description":"Validation Error. The request includes one or more invalid params. Please check the request params and try again.","content":{"application/json":{"schema":{"title":"unprocessableEntityResponse","type":"object","properties":{"message":{"type":"string"},"type":{"type":"string","enum":["gateway_timeout","service_unavailable","bad_gateway","internal_server_error","unprocessable_entity","not_found","forbidden","unauthorized","invalid_request","invalid_token","insufficient_scope","service_error","invalid_path","rate_limit_exceeded"]},"success":{"type":"boolean"}}},"example":{"message":"The request was well-formed but was unable to be followed due to semantic errors","type":"unprocessable_entity","success":false}}}},"429":{"description":"Rate-limit exceeded","content":{"application/json":{"schema":{"title":"rateLimitExceededResponse","type":"object","properties":{"message":{"type":"string"},"type":{"type":"string","enum":["gateway_timeout","service_unavailable","bad_gateway","internal_server_error","unprocessable_entity","not_found","forbidden","unauthorized","invalid_request","invalid_token","insufficient_scope","service_error","invalid_path","rate_limit_exceeded"]},"success":{"type":"boolean"}}},"example":{"message":"Too many requests, please try again later","type":"rate_limit_exceeded","success":false}}}},"500":{"description":"Server Error. Something went wrong, try again later.","content":{"application/json":{"schema":{"title":"internalServerErrorResponse","type":"object","properties":{"message":{"type":"string"},"type":{"type":"string","enum":["gateway_timeout","service_unavailable","bad_gateway","internal_server_error","unprocessable_entity","not_found","forbidden","unauthorized","invalid_request","invalid_token","insufficient_scope","service_error","invalid_path","rate_limit_exceeded"]},"success":{"type":"boolean"}}},"example":{"message":"The server encountered an internal error and was unable to complete your request","type":"internal_server_error","success":false}}}},"502":{"description":"Bad Gateway","content":{"application/json":{"schema":{"title":"badGatewayResponse","type":"object","properties":{"message":{"type":"string"},"type":{"type":"string","enum":["gateway_timeout","service_unavailable","bad_gateway","internal_server_error","unprocessable_entity","not_found","forbidden","unauthorized","invalid_request","invalid_token","insufficient_scope","service_error","invalid_path","rate_limit_exceeded"]},"success":{"type":"boolean"}}},"example":{"message":"The server was acting as a gateway or proxy and received an invalid response from the upstream server","type":"bad_gateway","success":false}}}},"503":{"description":"Service Unavailable","content":{"application/json":{"schema":{"title":"serviceUnavailableResponse","type":"object","properties":{"message":{"type":"string"},"type":{"type":"string","enum":["gateway_timeout","service_unavailable","bad_gateway","internal_server_error","unprocessable_entity","not_found","forbidden","unauthorized","invalid_request","invalid_token","insufficient_scope","service_error","invalid_path","rate_limit_exceeded"]},"success":{"type":"boolean"}}},"example":{"message":"The server is currently unable to handle the request due to a temporary overload or scheduled maintenance","type":"service_unavailable","success":false}}}},"504":{"description":"Gateway Timeout","content":{"application/json":{"schema":{"title":"gatewayTimeoutResponse","type":"object","properties":{"message":{"type":"string"},"type":{"type":"string","enum":["gateway_timeout","service_unavailable","bad_gateway","internal_server_error","unprocessable_entity","not_found","forbidden","unauthorized","invalid_request","invalid_token","insufficient_scope","service_error","invalid_path","rate_limit_exceeded"]},"success":{"type":"boolean"}}},"example":{"message":"The server was acting as a gateway or proxy and did not receive a timely response from the upstream server","type":"gateway_timeout","success":false}}}}},"x-code-samples":[{"lang":"javascript","label":"Node.js","source":"// List of Chapter Reciters\nconst axios = require('axios');\n\nconst API_BASE_URL = 'https://apis.quran.foundation/content/api/v4';\nconst ACCESS_TOKEN = '';\nconst CLIENT_ID = '';\n\nasync function callApi(options = {}) {\n const response = await axios.get(\n `${API_BASE_URL}/resources/chapter_reciters`,\n {\n headers: {\n 'x-auth-token': ACCESS_TOKEN,\n 'x-client-id': CLIENT_ID\n },\n params: options\n }\n );\n return response.data;\n}\n\n// Example usage\ncallApi({\"language\":\"en\"})\n .then(data => console.log(data))\n .catch(err => console.error(err.response?.status, err.message));"},{"lang":"python","label":"Python","source":"# List of Chapter Reciters\nimport requests\n\nAPI_BASE_URL = 'https://apis.quran.foundation/content/api/v4'\nACCESS_TOKEN = ''\nCLIENT_ID = ''\n\ndef call_api(language=None):\n params = {k: v for k, v in {'language': language}.items() if v is not None}\n \n response = requests.get(\n f'{API_BASE_URL}/resources/chapter_reciters',\n headers={\n 'x-auth-token': ACCESS_TOKEN,\n 'x-client-id': CLIENT_ID\n },\n params=params\n )\n response.raise_for_status()\n return response.json()\n\n# Example usage\ntry:\n data = call_api(language=\"en\")\n print(data)\nexcept requests.HTTPError as e:\n print(f'Error {e.response.status_code}: {e}')"},{"lang":"go","label":"Go","source":"// List of Chapter Reciters\npackage main\n\nimport (\n \"fmt\"\n \"io\"\n \"net/http\"\n \"net/url\"\n)\n\nconst API_BASE_URL = \"https://apis.quran.foundation/content/api/v4\"\nconst ACCESS_TOKEN = \"\"\nconst CLIENT_ID = \"\"\n\nfunc callApi(params map[string]string) (string, error) {\n path := \"/resources/chapter_reciters\"\n endpoint := API_BASE_URL + path\n if params != nil && len(params) > 0 {\n values := url.Values{}\n for k, v := range params {\n values.Set(k, v)\n }\n endpoint = endpoint + \"?\" + values.Encode()\n }\n\n req, err := http.NewRequest(\"GET\", endpoint, nil)\n if err != nil {\n return \"\", err\n }\n req.Header.Set(\"x-auth-token\", ACCESS_TOKEN)\n req.Header.Set(\"x-client-id\", CLIENT_ID)\n\n resp, err := http.DefaultClient.Do(req)\n if err != nil {\n return \"\", err\n }\n defer resp.Body.Close()\n\n body, err := io.ReadAll(resp.Body)\n if err != nil {\n return \"\", err\n }\n return string(body), nil\n}\n\n// Example usage\nfunc main() {\n params := map[string]string{\"language\": \"en\"}\n data, err := callApi(params)\n if err != nil {\n fmt.Println(\"Error:\", err)\n return\n }\n fmt.Println(data)\n}"},{"lang":"ruby","label":"Ruby","source":"# List of Chapter Reciters\nrequire \"net/http\"\nrequire \"uri\"\n\nAPI_BASE_URL = \"https://apis.quran.foundation/content/api/v4\"\nACCESS_TOKEN = \"\"\nCLIENT_ID = \"\"\n\ndef call_api(params = {})\n path = \"/resources/chapter_reciters\"\n uri = URI(API_BASE_URL + path)\n uri.query = URI.encode_www_form(params) if params && !params.empty?\n request_class = Net::HTTP.const_get(\"Get\")\n request = request_class.new(uri)\n request[\"x-auth-token\"] = ACCESS_TOKEN\n request[\"x-client-id\"] = CLIENT_ID\n\n response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|\n http.request(request)\n end\n\n response.body\nend\n\n# Example usage\nparams = { \"language\" => \"en\" }\ndata = call_api(params)\nputs data"},{"lang":"csharp","label":"C#","source":"// List of Chapter Reciters\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Net.Http;\nusing System.Threading.Tasks;\n\nconst string API_BASE_URL = \"https://apis.quran.foundation/content/api/v4\";\nconst string ACCESS_TOKEN = \"\";\nconst string CLIENT_ID = \"\";\n\nstatic async Task CallApiAsync(Dictionary query = null)\n{\n var path = $@\"/resources/chapter_reciters\";\n var url = API_BASE_URL + path;\n if (query != null && query.Count > 0)\n {\n var queryString = string.Join(\"&\", query.Select(kvp =>\n $\"{Uri.EscapeDataString(kvp.Key)}={Uri.EscapeDataString(kvp.Value)}\"));\n url = $\"{url}?{queryString}\";\n }\n using var client = new HttpClient();\n using var request = new HttpRequestMessage(new HttpMethod(\"GET\"), url);\n request.Headers.Add(\"x-auth-token\", ACCESS_TOKEN);\n request.Headers.Add(\"x-client-id\", CLIENT_ID);\n\n using var response = await client.SendAsync(request);\n response.EnsureSuccessStatusCode();\n return await response.Content.ReadAsStringAsync();\n}\n\n// Example usage\nvar query = new Dictionary { {\"language\", \"en\"} };\nvar data = await CallApiAsync(query);\nConsole.WriteLine(data);"},{"lang":"php","label":"PHP","source":"# List of Chapter Reciters\n';\nconst CLIENT_ID = '';\n\nfunction callApi($params = []) {\n $path = \"/resources/chapter_reciters\";\n $url = API_BASE_URL . $path;\n if (!empty($params)) {\n $url .= '?' . http_build_query($params);\n }\n $ch = curl_init($url);\n curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);\n curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');\n curl_setopt($ch, CURLOPT_HTTPHEADER, [\n 'x-auth-token: ' . ACCESS_TOKEN,\n 'x-client-id: ' . CLIENT_ID\n ]);\n\n $response = curl_exec($ch);\n if ($response === false) {\n throw new Exception(curl_error($ch));\n }\n curl_close($ch);\n return $response;\n}\n\n// Example usage\n$params = ['language' => 'en'];\n$data = callApi($params);\necho $data;\n?>"},{"lang":"java","label":"Java","source":"// List of Chapter Reciters\nimport java.io.IOException;\nimport java.util.HashMap;\nimport java.util.Map;\nimport okhttp3.HttpUrl;\nimport okhttp3.OkHttpClient;\nimport okhttp3.Request;\nimport okhttp3.RequestBody;\nimport okhttp3.Response;\n\npublic class Main {\n private static final String API_BASE_URL = \"https://apis.quran.foundation/content/api/v4\";\n private static final String ACCESS_TOKEN = \"\";\n private static final String CLIENT_ID = \"\";\n\n public static String callApi(Map params) throws IOException {\n String path = \"/resources/chapter_reciters\";\n HttpUrl.Builder urlBuilder = HttpUrl.parse(API_BASE_URL + path).newBuilder();\n if (params != null) {\n for (Map.Entry entry : params.entrySet()) {\n urlBuilder.addQueryParameter(entry.getKey(), entry.getValue());\n }\n }\n String method = \"GET\";\n RequestBody requestBody = method.equals(\"GET\") ? null : RequestBody.create(new byte[0]);\n Request request = new Request.Builder()\n .url(urlBuilder.build())\n .addHeader(\"x-auth-token\", ACCESS_TOKEN)\n .addHeader(\"x-client-id\", CLIENT_ID)\n .method(method, requestBody)\n .build();\n\n OkHttpClient client = new OkHttpClient();\n Response response = client.newCall(request).execute();\n return response.body().string();\n }\n\n public static void main(String[] args) throws Exception {\n Map params = new HashMap<>();\n params.put(\"language\", \"en\");\n String data = callApi(params);\n System.out.println(data);\n }\n}"},{"lang":"powershell","label":"PowerShell","source":"# List of Chapter Reciters\n$API_BASE_URL = \"https://apis.quran.foundation/content/api/v4\"\n$ACCESS_TOKEN = \"\"\n$CLIENT_ID = \"\"\n\nfunction Call-Api([hashtable]$params = @{}) {\n $path = \"/resources/chapter_reciters\"\n $url = \"$API_BASE_URL$path\"\n if ($params.Count -gt 0) {\n $query = ($params.GetEnumerator() | ForEach-Object {\n \"$($_.Key)=$([System.Uri]::EscapeDataString([string]$_.Value))\"\n }) -join \"&\"\n $url = \"$url?$query\"\n }\n $headers = @{\n \"x-auth-token\" = $ACCESS_TOKEN\n \"x-client-id\" = $CLIENT_ID\n }\n\n Invoke-RestMethod -Method GET -Uri $url -Headers $headers\n}\n\n# Example usage\n$params = @{ language = \"en\" }\n$data = Call-Api($params)\nWrite-Output $data"},{"lang":"bash","label":"cURL","source":"# List of Chapter Reciters\ncurl -X GET \\\n 'https://apis.quran.foundation/content/api/v4/resources/chapter_reciters?language=en' \\\n -H 'x-auth-token: ' \\\n -H 'x-client-id: '"},{"lang":"text","label":"🤖 AI Prompt","source":"Implement a function to list of chapter reciters using the Quran Foundation API.\n\nEndpoint: GET /resources/chapter_reciters\nBase URL: https://apis.quran.foundation/content/api/v4\n\nRequired Headers (copy exactly):\n x-auth-token: \n x-client-id: \nOptional Query Parameters:\n language: Name of reciters in specific language. Will fallback to English if we don't have names in specific language.\n\nNotes:\n This endpoint returns chapter-reciter IDs.\n Use these IDs with `/chapter_recitations/{reciter_id}`, `/chapter_recitations/{reciter_id}/{chapter_number}`, `/audio/reciters/{reciter_id}/timestamp`, and `/audio/reciters/{reciter_id}/lookup`.\n These IDs are not interchangeable with ayah-by-ayah recitation IDs from `/resources/recitations`.\n\nImplementation Requirements:\n1. Build the request URL: {baseUrl}/resources/chapter_reciters?{queryParams}\n2. Inject both required headers on every request\n3. Handle errors safely:\n - 401: Token expired → re-request token and retry once\n - 403: Access denied → check client credentials\n - 429: Rate limited → implement exponential backoff\n\nAcceptance Checklist:\n- [ ] Function accepts optional parameters\n- [ ] Headers x-auth-token and x-client-id are sent\n- [ ] 401/403/429 errors are handled gracefully"}],"extensions":[{"key":"x-code-samples","value":[{"lang":"javascript","label":"Node.js","source":"// List of Chapter Reciters\nconst axios = require('axios');\n\nconst API_BASE_URL = 'https://apis.quran.foundation/content/api/v4';\nconst ACCESS_TOKEN = '';\nconst CLIENT_ID = '';\n\nasync function callApi(options = {}) {\n const response = await axios.get(\n `${API_BASE_URL}/resources/chapter_reciters`,\n {\n headers: {\n 'x-auth-token': ACCESS_TOKEN,\n 'x-client-id': CLIENT_ID\n },\n params: options\n }\n );\n return response.data;\n}\n\n// Example usage\ncallApi({\"language\":\"en\"})\n .then(data => console.log(data))\n .catch(err => console.error(err.response?.status, err.message));"},{"lang":"python","label":"Python","source":"# List of Chapter Reciters\nimport requests\n\nAPI_BASE_URL = 'https://apis.quran.foundation/content/api/v4'\nACCESS_TOKEN = ''\nCLIENT_ID = ''\n\ndef call_api(language=None):\n params = {k: v for k, v in {'language': language}.items() if v is not None}\n \n response = requests.get(\n f'{API_BASE_URL}/resources/chapter_reciters',\n headers={\n 'x-auth-token': ACCESS_TOKEN,\n 'x-client-id': CLIENT_ID\n },\n params=params\n )\n response.raise_for_status()\n return response.json()\n\n# Example usage\ntry:\n data = call_api(language=\"en\")\n print(data)\nexcept requests.HTTPError as e:\n print(f'Error {e.response.status_code}: {e}')"},{"lang":"go","label":"Go","source":"// List of Chapter Reciters\npackage main\n\nimport (\n \"fmt\"\n \"io\"\n \"net/http\"\n \"net/url\"\n)\n\nconst API_BASE_URL = \"https://apis.quran.foundation/content/api/v4\"\nconst ACCESS_TOKEN = \"\"\nconst CLIENT_ID = \"\"\n\nfunc callApi(params map[string]string) (string, error) {\n path := \"/resources/chapter_reciters\"\n endpoint := API_BASE_URL + path\n if params != nil && len(params) > 0 {\n values := url.Values{}\n for k, v := range params {\n values.Set(k, v)\n }\n endpoint = endpoint + \"?\" + values.Encode()\n }\n\n req, err := http.NewRequest(\"GET\", endpoint, nil)\n if err != nil {\n return \"\", err\n }\n req.Header.Set(\"x-auth-token\", ACCESS_TOKEN)\n req.Header.Set(\"x-client-id\", CLIENT_ID)\n\n resp, err := http.DefaultClient.Do(req)\n if err != nil {\n return \"\", err\n }\n defer resp.Body.Close()\n\n body, err := io.ReadAll(resp.Body)\n if err != nil {\n return \"\", err\n }\n return string(body), nil\n}\n\n// Example usage\nfunc main() {\n params := map[string]string{\"language\": \"en\"}\n data, err := callApi(params)\n if err != nil {\n fmt.Println(\"Error:\", err)\n return\n }\n fmt.Println(data)\n}"},{"lang":"ruby","label":"Ruby","source":"# List of Chapter Reciters\nrequire \"net/http\"\nrequire \"uri\"\n\nAPI_BASE_URL = \"https://apis.quran.foundation/content/api/v4\"\nACCESS_TOKEN = \"\"\nCLIENT_ID = \"\"\n\ndef call_api(params = {})\n path = \"/resources/chapter_reciters\"\n uri = URI(API_BASE_URL + path)\n uri.query = URI.encode_www_form(params) if params && !params.empty?\n request_class = Net::HTTP.const_get(\"Get\")\n request = request_class.new(uri)\n request[\"x-auth-token\"] = ACCESS_TOKEN\n request[\"x-client-id\"] = CLIENT_ID\n\n response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|\n http.request(request)\n end\n\n response.body\nend\n\n# Example usage\nparams = { \"language\" => \"en\" }\ndata = call_api(params)\nputs data"},{"lang":"csharp","label":"C#","source":"// List of Chapter Reciters\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Net.Http;\nusing System.Threading.Tasks;\n\nconst string API_BASE_URL = \"https://apis.quran.foundation/content/api/v4\";\nconst string ACCESS_TOKEN = \"\";\nconst string CLIENT_ID = \"\";\n\nstatic async Task CallApiAsync(Dictionary query = null)\n{\n var path = $@\"/resources/chapter_reciters\";\n var url = API_BASE_URL + path;\n if (query != null && query.Count > 0)\n {\n var queryString = string.Join(\"&\", query.Select(kvp =>\n $\"{Uri.EscapeDataString(kvp.Key)}={Uri.EscapeDataString(kvp.Value)}\"));\n url = $\"{url}?{queryString}\";\n }\n using var client = new HttpClient();\n using var request = new HttpRequestMessage(new HttpMethod(\"GET\"), url);\n request.Headers.Add(\"x-auth-token\", ACCESS_TOKEN);\n request.Headers.Add(\"x-client-id\", CLIENT_ID);\n\n using var response = await client.SendAsync(request);\n response.EnsureSuccessStatusCode();\n return await response.Content.ReadAsStringAsync();\n}\n\n// Example usage\nvar query = new Dictionary { {\"language\", \"en\"} };\nvar data = await CallApiAsync(query);\nConsole.WriteLine(data);"},{"lang":"php","label":"PHP","source":"# List of Chapter Reciters\n';\nconst CLIENT_ID = '';\n\nfunction callApi($params = []) {\n $path = \"/resources/chapter_reciters\";\n $url = API_BASE_URL . $path;\n if (!empty($params)) {\n $url .= '?' . http_build_query($params);\n }\n $ch = curl_init($url);\n curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);\n curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');\n curl_setopt($ch, CURLOPT_HTTPHEADER, [\n 'x-auth-token: ' . ACCESS_TOKEN,\n 'x-client-id: ' . CLIENT_ID\n ]);\n\n $response = curl_exec($ch);\n if ($response === false) {\n throw new Exception(curl_error($ch));\n }\n curl_close($ch);\n return $response;\n}\n\n// Example usage\n$params = ['language' => 'en'];\n$data = callApi($params);\necho $data;\n?>"},{"lang":"java","label":"Java","source":"// List of Chapter Reciters\nimport java.io.IOException;\nimport java.util.HashMap;\nimport java.util.Map;\nimport okhttp3.HttpUrl;\nimport okhttp3.OkHttpClient;\nimport okhttp3.Request;\nimport okhttp3.RequestBody;\nimport okhttp3.Response;\n\npublic class Main {\n private static final String API_BASE_URL = \"https://apis.quran.foundation/content/api/v4\";\n private static final String ACCESS_TOKEN = \"\";\n private static final String CLIENT_ID = \"\";\n\n public static String callApi(Map params) throws IOException {\n String path = \"/resources/chapter_reciters\";\n HttpUrl.Builder urlBuilder = HttpUrl.parse(API_BASE_URL + path).newBuilder();\n if (params != null) {\n for (Map.Entry entry : params.entrySet()) {\n urlBuilder.addQueryParameter(entry.getKey(), entry.getValue());\n }\n }\n String method = \"GET\";\n RequestBody requestBody = method.equals(\"GET\") ? null : RequestBody.create(new byte[0]);\n Request request = new Request.Builder()\n .url(urlBuilder.build())\n .addHeader(\"x-auth-token\", ACCESS_TOKEN)\n .addHeader(\"x-client-id\", CLIENT_ID)\n .method(method, requestBody)\n .build();\n\n OkHttpClient client = new OkHttpClient();\n Response response = client.newCall(request).execute();\n return response.body().string();\n }\n\n public static void main(String[] args) throws Exception {\n Map params = new HashMap<>();\n params.put(\"language\", \"en\");\n String data = callApi(params);\n System.out.println(data);\n }\n}"},{"lang":"powershell","label":"PowerShell","source":"# List of Chapter Reciters\n$API_BASE_URL = \"https://apis.quran.foundation/content/api/v4\"\n$ACCESS_TOKEN = \"\"\n$CLIENT_ID = \"\"\n\nfunction Call-Api([hashtable]$params = @{}) {\n $path = \"/resources/chapter_reciters\"\n $url = \"$API_BASE_URL$path\"\n if ($params.Count -gt 0) {\n $query = ($params.GetEnumerator() | ForEach-Object {\n \"$($_.Key)=$([System.Uri]::EscapeDataString([string]$_.Value))\"\n }) -join \"&\"\n $url = \"$url?$query\"\n }\n $headers = @{\n \"x-auth-token\" = $ACCESS_TOKEN\n \"x-client-id\" = $CLIENT_ID\n }\n\n Invoke-RestMethod -Method GET -Uri $url -Headers $headers\n}\n\n# Example usage\n$params = @{ language = \"en\" }\n$data = Call-Api($params)\nWrite-Output $data"},{"lang":"bash","label":"cURL","source":"# List of Chapter Reciters\ncurl -X GET \\\n 'https://apis.quran.foundation/content/api/v4/resources/chapter_reciters?language=en' \\\n -H 'x-auth-token: ' \\\n -H 'x-client-id: '"},{"lang":"text","label":"🤖 AI Prompt","source":"Implement a function to list of chapter reciters using the Quran Foundation API.\n\nEndpoint: GET /resources/chapter_reciters\nBase URL: https://apis.quran.foundation/content/api/v4\n\nRequired Headers (copy exactly):\n x-auth-token: \n x-client-id: \nOptional Query Parameters:\n language: Name of reciters in specific language. Will fallback to English if we don't have names in specific language.\n\nNotes:\n This endpoint returns chapter-reciter IDs.\n Use these IDs with `/chapter_recitations/{reciter_id}`, `/chapter_recitations/{reciter_id}/{chapter_number}`, `/audio/reciters/{reciter_id}/timestamp`, and `/audio/reciters/{reciter_id}/lookup`.\n These IDs are not interchangeable with ayah-by-ayah recitation IDs from `/resources/recitations`.\n\nImplementation Requirements:\n1. Build the request URL: {baseUrl}/resources/chapter_reciters?{queryParams}\n2. Inject both required headers on every request\n3. Handle errors safely:\n - 401: Token expired → re-request token and retry once\n - 403: Access denied → check client credentials\n - 429: Rate limited → implement exponential backoff\n\nAcceptance Checklist:\n- [ ] Function accepts optional parameters\n- [ ] Headers x-auth-token and x-client-id are sent\n- [ ] 401/403/429 errors are handled gracefully"}]}],"method":"get","path":"/resources/chapter_reciters","servers":[{"url":"https://apis-prelive.quran.foundation/content/api/v4","description":"Pre-production Server"},{"url":"https://apis.quran.foundation/content/api/v4","description":"Production Server"}],"security":[{"x-auth-token":[],"x-client-id":[]}],"securitySchemes":{"x-auth-token":{"type":"apiKey","description":"The access token required for accessing the endpoints.","name":"x-auth-token","in":"header"},"x-client-id":{"type":"apiKey","description":"Your client Id","name":"x-client-id","in":"header"}},"info":{"title":"Content APIs","description":"Quran.Foundation Content APIs offer programmatic access to the Quran's core content like chapters, verses, recitations, translations, and more, distinct from user-specific data like notes and bookmarks provided by [User-related APIs](/docs/category/user-related-apis).\n\n:::important Integrity of Translations\nPlease **disable any automatic browser-translation features** (e.g. Google-Translate-in-Chrome) when displaying text returned by the *Translations* endpoints. \nRe-translating an already vetted Quranic translation can introduce serious semantic errors.\n:::\n\n ## How to get access \n\n We are using OAuth2 flows to authenticate and authorize requests. To get started, you need to [get an access token](/docs/tutorials/oidc/getting-started-with-oauth2#obtaining-oauth-20-client-credentials) to make requests to our APIs. Since the APIs are not user-related, you will need to use the `client_credentials` grant type and [`content` scope](/docs/user_related_apis_versioned/scopes#content) when sending a request to [The OAuth 2.0 Token Endpoint](/docs/oauth2_apis_versioned/oauth-2-token-exchange) to get the access token. \n\n```mermaid\nsequenceDiagram\n participant App as Your App\n participant Auth as Quran.Foundation
Authorization Server\n participant API as Quran.Foundation
Resources Server\n\n App->>Auth: Request Token with Client Credentials\n Auth-->>App: Token Response (access_token)\n App->>API: Use token to call API\n API-->>App: Requested resource\n\n Note over App,Auth: Access token expires (1 hour)\n\n App->>Auth: Re-issue access_token using client_credentials\n Auth-->>App: New access_token\n```\n\n After getting a valid access token, each request to get resources will have to include 2 headers mentioned below: `x-auth-token` and `x-client-id`. This spec also includes a small subset of Quran Reflect post-read endpoints that are compatible with the `client_credentials` grant. These operations still require `x-auth-token` and `x-client-id`, but they do not use the `content` scope. Use `post.read` for `/quran-reflect/v1/posts/feed`, `/quran-reflect/v1/posts/{id}`, and `/quran-reflect/v1/posts/user-posts/{id}`. Use `comment.read` for `/quran-reflect/v1/posts/{id}/comments` and `/quran-reflect/v1/posts/{id}/all-comments`. These are Quran Reflect gateway endpoints, not `/content/api/v4/...` endpoints.","version":"v4"},"postman":{"name":"List of Chapter Reciters","description":{"content":"Get list of available chapter reciters. Use these IDs with `/chapter_recitations/{reciter_id}`, `/chapter_recitations/{reciter_id}/{chapter_number}`, `/audio/reciters/{reciter_id}/timestamp`, and `/audio/reciters/{reciter_id}/lookup`. These IDs are not interchangeable with ayah-by-ayah recitation IDs from `/resources/recitations`.","type":"text/plain"},"url":{"path":["resources","chapter_reciters"],"host":["{{baseUrl}}"],"query":[{"disabled":false,"description":{"content":"Name of reciters in specific language. Will fallback to English if we don't have names in specific language.","type":"text/plain"},"key":"language","value":""}],"variable":[]},"header":[{"key":"Accept","value":"application/json"}],"method":"GET"}} +api: {"tags":["Audio"],"description":"Get list of available chapter reciters. Use these IDs with `/chapter_recitations/{reciter_id}`, `/chapter_recitations/{reciter_id}/{chapter_number}`, `/audio/reciters/{reciter_id}/timestamp`, and `/audio/reciters/{reciter_id}/lookup`. These IDs are not interchangeable with ayah-by-ayah recitation IDs from `/resources/recitations`.","operationId":"chapter-reciters","parameters":[{"name":"language","in":"query","description":"Name of reciters in specific language. Will fallback to English if we don't have names in specific language.","schema":{"type":"string","default":"en"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","required":["reciters"],"properties":{"reciters":{"type":"array","items":{"title":"Chapter Reciters","required":["id","name","style","qirat","reciter_id","beta"],"type":"object","properties":{"id":{"type":"integer","description":"Chapter-reciter ID. Use it as `reciter_id` in [/chapter_recitations/{reciter_id}](/docs/content_apis_versioned/chapter-reciter-audio-files)."},"reciter_id":{"type":"integer","nullable":true,"description":"ID of the person reciting. Several chapter reciters (for example, Murattal and Mujawwad styles of the same reciter) can share one `reciter_id`."},"name":{"type":"string","description":"Name of reciter in English"},"beta":{"type":"boolean","description":"`true` when Quran.com marks the recitation as beta."},"style":{"type":"object","properties":{"name":{"type":"string","nullable":true},"language_name":{"type":"string"}},"required":["language_name"]},"qirat":{"type":"object","properties":{"name":{"type":"string","nullable":true},"language_name":{"type":"string"}},"required":["language_name"]},"translated_name":{"nullable":true,"allOf":[{"title":"TranslatedName","required":["language_name","name"],"type":"object","properties":{"language_name":{"type":"string","default":"english"},"name":{"type":"string","description":"Name of the resource in specific language."}},"example":{"language_name":"english","name":"The Opener"}}]}},"example":{"id":4,"reciter_id":3,"name":"Abu Bakr al-Shatri","beta":false,"style":{"name":"Murattal","language_name":"english"},"qirat":{"name":"Hafs","language_name":"english"},"translated_name":{"name":"Abu Bakr al-Shatri","language_name":"english"}}}}}},"examples":{"default_success":{"summary":"Successful response","value":{"reciters":[{"id":4,"reciter_id":3,"name":"Abu Bakr al-Shatri","beta":false,"style":{"name":"Murattal","language_name":"english"},"qirat":{"name":"Hafs","language_name":"english"},"translated_name":{"name":"Abu Bakr al-Shatri","language_name":"english"}}]}}}}}},"400":{"description":"Will be returned when the request is invalid e.g. request is missing required headers or with invalid query parameters.","content":{"application/json":{"schema":{"title":"invalidRequestResponse","type":"object","properties":{"message":{"type":"string"},"type":{"type":"string","enum":["gateway_timeout","service_unavailable","bad_gateway","internal_server_error","unprocessable_entity","not_found","forbidden","unauthorized","invalid_request","invalid_token","insufficient_scope","service_error","invalid_path","rate_limit_exceeded"]},"success":{"type":"boolean"}}},"example":{"message":"The request is missing required headers or is invalid","type":"invalid_request","success":false}}}},"401":{"description":"Will be returned when the request is unauthorized.","content":{"application/json":{"schema":{"title":"unauthorizedResponse","type":"object","properties":{"message":{"type":"string"},"type":{"type":"string","enum":["gateway_timeout","service_unavailable","bad_gateway","internal_server_error","unprocessable_entity","not_found","forbidden","unauthorized","invalid_request","invalid_token","insufficient_scope","service_error","invalid_path","rate_limit_exceeded"]},"success":{"type":"boolean"}}},"example":{"message":"The request requires user authentication","type":"unauthorized","success":false}}}},"403":{"description":"The request is forbidden, for example because a valid access token lacks the required scope or the client lacks permission.","content":{"application/json":{"schema":{"title":"forbiddenResponse","type":"object","properties":{"message":{"type":"string"},"type":{"type":"string","enum":["gateway_timeout","service_unavailable","bad_gateway","internal_server_error","unprocessable_entity","not_found","forbidden","unauthorized","invalid_request","invalid_token","insufficient_scope","service_error","invalid_path","rate_limit_exceeded"]},"success":{"type":"boolean"}}},"example":{"message":"The server understood the request, but refuses to authorize it","type":"forbidden","success":false}}}},"404":{"description":"Not Found. The resource being accessed does not exist.","content":{"application/json":{"schema":{"title":"notFoundResponse","type":"object","properties":{"message":{"type":"string"},"type":{"type":"string","enum":["gateway_timeout","service_unavailable","bad_gateway","internal_server_error","unprocessable_entity","not_found","forbidden","unauthorized","invalid_request","invalid_token","insufficient_scope","service_error","invalid_path","rate_limit_exceeded"]},"success":{"type":"boolean"}}},"example":{"message":"The requested resource could not be found","type":"not_found","success":false}}}},"422":{"description":"Validation Error. The request includes one or more invalid params. Please check the request params and try again.","content":{"application/json":{"schema":{"title":"unprocessableEntityResponse","type":"object","properties":{"message":{"type":"string"},"type":{"type":"string","enum":["gateway_timeout","service_unavailable","bad_gateway","internal_server_error","unprocessable_entity","not_found","forbidden","unauthorized","invalid_request","invalid_token","insufficient_scope","service_error","invalid_path","rate_limit_exceeded"]},"success":{"type":"boolean"}}},"example":{"message":"The request was well-formed but was unable to be followed due to semantic errors","type":"unprocessable_entity","success":false}}}},"429":{"description":"Rate-limit exceeded","content":{"application/json":{"schema":{"title":"rateLimitExceededResponse","type":"object","properties":{"message":{"type":"string"},"type":{"type":"string","enum":["gateway_timeout","service_unavailable","bad_gateway","internal_server_error","unprocessable_entity","not_found","forbidden","unauthorized","invalid_request","invalid_token","insufficient_scope","service_error","invalid_path","rate_limit_exceeded"]},"success":{"type":"boolean"}}},"example":{"message":"Too many requests, please try again later","type":"rate_limit_exceeded","success":false}}}},"500":{"description":"Server Error. Something went wrong, try again later.","content":{"application/json":{"schema":{"title":"internalServerErrorResponse","type":"object","properties":{"message":{"type":"string"},"type":{"type":"string","enum":["gateway_timeout","service_unavailable","bad_gateway","internal_server_error","unprocessable_entity","not_found","forbidden","unauthorized","invalid_request","invalid_token","insufficient_scope","service_error","invalid_path","rate_limit_exceeded"]},"success":{"type":"boolean"}}},"example":{"message":"The server encountered an internal error and was unable to complete your request","type":"internal_server_error","success":false}}}},"502":{"description":"Bad Gateway","content":{"application/json":{"schema":{"title":"badGatewayResponse","type":"object","properties":{"message":{"type":"string"},"type":{"type":"string","enum":["gateway_timeout","service_unavailable","bad_gateway","internal_server_error","unprocessable_entity","not_found","forbidden","unauthorized","invalid_request","invalid_token","insufficient_scope","service_error","invalid_path","rate_limit_exceeded"]},"success":{"type":"boolean"}}},"example":{"message":"The server was acting as a gateway or proxy and received an invalid response from the upstream server","type":"bad_gateway","success":false}}}},"503":{"description":"Service Unavailable","content":{"application/json":{"schema":{"title":"serviceUnavailableResponse","type":"object","properties":{"message":{"type":"string"},"type":{"type":"string","enum":["gateway_timeout","service_unavailable","bad_gateway","internal_server_error","unprocessable_entity","not_found","forbidden","unauthorized","invalid_request","invalid_token","insufficient_scope","service_error","invalid_path","rate_limit_exceeded"]},"success":{"type":"boolean"}}},"example":{"message":"The server is currently unable to handle the request due to a temporary overload or scheduled maintenance","type":"service_unavailable","success":false}}}},"504":{"description":"Gateway Timeout","content":{"application/json":{"schema":{"title":"gatewayTimeoutResponse","type":"object","properties":{"message":{"type":"string"},"type":{"type":"string","enum":["gateway_timeout","service_unavailable","bad_gateway","internal_server_error","unprocessable_entity","not_found","forbidden","unauthorized","invalid_request","invalid_token","insufficient_scope","service_error","invalid_path","rate_limit_exceeded"]},"success":{"type":"boolean"}}},"example":{"message":"The server was acting as a gateway or proxy and did not receive a timely response from the upstream server","type":"gateway_timeout","success":false}}}}},"x-code-samples":[{"lang":"javascript","label":"Node.js","source":"// List of Chapter Reciters\nconst axios = require('axios');\n\nconst API_BASE_URL = 'https://apis.quran.foundation/content/api/v4';\nconst ACCESS_TOKEN = '';\nconst CLIENT_ID = '';\n\nasync function callApi(options = {}) {\n const response = await axios.get(\n `${API_BASE_URL}/resources/chapter_reciters`,\n {\n headers: {\n 'x-auth-token': ACCESS_TOKEN,\n 'x-client-id': CLIENT_ID\n },\n params: options\n }\n );\n return response.data;\n}\n\n// Example usage\ncallApi({\"language\":\"en\"})\n .then(data => console.log(data))\n .catch(err => console.error(err.response?.status, err.message));"},{"lang":"python","label":"Python","source":"# List of Chapter Reciters\nimport requests\n\nAPI_BASE_URL = 'https://apis.quran.foundation/content/api/v4'\nACCESS_TOKEN = ''\nCLIENT_ID = ''\n\ndef call_api(language=None):\n params = {k: v for k, v in {'language': language}.items() if v is not None}\n \n response = requests.get(\n f'{API_BASE_URL}/resources/chapter_reciters',\n headers={\n 'x-auth-token': ACCESS_TOKEN,\n 'x-client-id': CLIENT_ID\n },\n params=params\n )\n response.raise_for_status()\n return response.json()\n\n# Example usage\ntry:\n data = call_api(language=\"en\")\n print(data)\nexcept requests.HTTPError as e:\n print(f'Error {e.response.status_code}: {e}')"},{"lang":"go","label":"Go","source":"// List of Chapter Reciters\npackage main\n\nimport (\n \"fmt\"\n \"io\"\n \"net/http\"\n \"net/url\"\n)\n\nconst API_BASE_URL = \"https://apis.quran.foundation/content/api/v4\"\nconst ACCESS_TOKEN = \"\"\nconst CLIENT_ID = \"\"\n\nfunc callApi(params map[string]string) (string, error) {\n path := \"/resources/chapter_reciters\"\n endpoint := API_BASE_URL + path\n if params != nil && len(params) > 0 {\n values := url.Values{}\n for k, v := range params {\n values.Set(k, v)\n }\n endpoint = endpoint + \"?\" + values.Encode()\n }\n\n req, err := http.NewRequest(\"GET\", endpoint, nil)\n if err != nil {\n return \"\", err\n }\n req.Header.Set(\"x-auth-token\", ACCESS_TOKEN)\n req.Header.Set(\"x-client-id\", CLIENT_ID)\n\n resp, err := http.DefaultClient.Do(req)\n if err != nil {\n return \"\", err\n }\n defer resp.Body.Close()\n\n body, err := io.ReadAll(resp.Body)\n if err != nil {\n return \"\", err\n }\n return string(body), nil\n}\n\n// Example usage\nfunc main() {\n params := map[string]string{\"language\": \"en\"}\n data, err := callApi(params)\n if err != nil {\n fmt.Println(\"Error:\", err)\n return\n }\n fmt.Println(data)\n}"},{"lang":"ruby","label":"Ruby","source":"# List of Chapter Reciters\nrequire \"net/http\"\nrequire \"uri\"\n\nAPI_BASE_URL = \"https://apis.quran.foundation/content/api/v4\"\nACCESS_TOKEN = \"\"\nCLIENT_ID = \"\"\n\ndef call_api(params = {})\n path = \"/resources/chapter_reciters\"\n uri = URI(API_BASE_URL + path)\n uri.query = URI.encode_www_form(params) if params && !params.empty?\n request_class = Net::HTTP.const_get(\"Get\")\n request = request_class.new(uri)\n request[\"x-auth-token\"] = ACCESS_TOKEN\n request[\"x-client-id\"] = CLIENT_ID\n\n response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|\n http.request(request)\n end\n\n response.body\nend\n\n# Example usage\nparams = { \"language\" => \"en\" }\ndata = call_api(params)\nputs data"},{"lang":"csharp","label":"C#","source":"// List of Chapter Reciters\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Net.Http;\nusing System.Threading.Tasks;\n\nconst string API_BASE_URL = \"https://apis.quran.foundation/content/api/v4\";\nconst string ACCESS_TOKEN = \"\";\nconst string CLIENT_ID = \"\";\n\nstatic async Task CallApiAsync(Dictionary query = null)\n{\n var path = $@\"/resources/chapter_reciters\";\n var url = API_BASE_URL + path;\n if (query != null && query.Count > 0)\n {\n var queryString = string.Join(\"&\", query.Select(kvp =>\n $\"{Uri.EscapeDataString(kvp.Key)}={Uri.EscapeDataString(kvp.Value)}\"));\n url = $\"{url}?{queryString}\";\n }\n using var client = new HttpClient();\n using var request = new HttpRequestMessage(new HttpMethod(\"GET\"), url);\n request.Headers.Add(\"x-auth-token\", ACCESS_TOKEN);\n request.Headers.Add(\"x-client-id\", CLIENT_ID);\n\n using var response = await client.SendAsync(request);\n response.EnsureSuccessStatusCode();\n return await response.Content.ReadAsStringAsync();\n}\n\n// Example usage\nvar query = new Dictionary { {\"language\", \"en\"} };\nvar data = await CallApiAsync(query);\nConsole.WriteLine(data);"},{"lang":"php","label":"PHP","source":"# List of Chapter Reciters\n';\nconst CLIENT_ID = '';\n\nfunction callApi($params = []) {\n $path = \"/resources/chapter_reciters\";\n $url = API_BASE_URL . $path;\n if (!empty($params)) {\n $url .= '?' . http_build_query($params);\n }\n $ch = curl_init($url);\n curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);\n curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');\n curl_setopt($ch, CURLOPT_HTTPHEADER, [\n 'x-auth-token: ' . ACCESS_TOKEN,\n 'x-client-id: ' . CLIENT_ID\n ]);\n\n $response = curl_exec($ch);\n if ($response === false) {\n throw new Exception(curl_error($ch));\n }\n curl_close($ch);\n return $response;\n}\n\n// Example usage\n$params = ['language' => 'en'];\n$data = callApi($params);\necho $data;\n?>"},{"lang":"java","label":"Java","source":"// List of Chapter Reciters\nimport java.io.IOException;\nimport java.util.HashMap;\nimport java.util.Map;\nimport okhttp3.HttpUrl;\nimport okhttp3.OkHttpClient;\nimport okhttp3.Request;\nimport okhttp3.RequestBody;\nimport okhttp3.Response;\n\npublic class Main {\n private static final String API_BASE_URL = \"https://apis.quran.foundation/content/api/v4\";\n private static final String ACCESS_TOKEN = \"\";\n private static final String CLIENT_ID = \"\";\n\n public static String callApi(Map params) throws IOException {\n String path = \"/resources/chapter_reciters\";\n HttpUrl.Builder urlBuilder = HttpUrl.parse(API_BASE_URL + path).newBuilder();\n if (params != null) {\n for (Map.Entry entry : params.entrySet()) {\n urlBuilder.addQueryParameter(entry.getKey(), entry.getValue());\n }\n }\n String method = \"GET\";\n RequestBody requestBody = method.equals(\"GET\") ? null : RequestBody.create(new byte[0]);\n Request request = new Request.Builder()\n .url(urlBuilder.build())\n .addHeader(\"x-auth-token\", ACCESS_TOKEN)\n .addHeader(\"x-client-id\", CLIENT_ID)\n .method(method, requestBody)\n .build();\n\n OkHttpClient client = new OkHttpClient();\n Response response = client.newCall(request).execute();\n return response.body().string();\n }\n\n public static void main(String[] args) throws Exception {\n Map params = new HashMap<>();\n params.put(\"language\", \"en\");\n String data = callApi(params);\n System.out.println(data);\n }\n}"},{"lang":"powershell","label":"PowerShell","source":"# List of Chapter Reciters\n$API_BASE_URL = \"https://apis.quran.foundation/content/api/v4\"\n$ACCESS_TOKEN = \"\"\n$CLIENT_ID = \"\"\n\nfunction Call-Api([hashtable]$params = @{}) {\n $path = \"/resources/chapter_reciters\"\n $url = \"$API_BASE_URL$path\"\n if ($params.Count -gt 0) {\n $query = ($params.GetEnumerator() | ForEach-Object {\n \"$($_.Key)=$([System.Uri]::EscapeDataString([string]$_.Value))\"\n }) -join \"&\"\n $url = \"$url?$query\"\n }\n $headers = @{\n \"x-auth-token\" = $ACCESS_TOKEN\n \"x-client-id\" = $CLIENT_ID\n }\n\n Invoke-RestMethod -Method GET -Uri $url -Headers $headers\n}\n\n# Example usage\n$params = @{ language = \"en\" }\n$data = Call-Api($params)\nWrite-Output $data"},{"lang":"bash","label":"cURL","source":"# List of Chapter Reciters\ncurl -X GET \\\n 'https://apis.quran.foundation/content/api/v4/resources/chapter_reciters?language=en' \\\n -H 'x-auth-token: ' \\\n -H 'x-client-id: '"},{"lang":"text","label":"🤖 AI Prompt","source":"Implement a function to list of chapter reciters using the Quran Foundation API.\n\nEndpoint: GET /resources/chapter_reciters\nBase URL: https://apis.quran.foundation/content/api/v4\n\nRequired Headers (copy exactly):\n x-auth-token: \n x-client-id: \nOptional Query Parameters:\n language: Name of reciters in specific language. Will fallback to English if we don't have names in specific language.\n\nNotes:\n This endpoint returns chapter-reciter IDs.\n Use these IDs with `/chapter_recitations/{reciter_id}`, `/chapter_recitations/{reciter_id}/{chapter_number}`, `/audio/reciters/{reciter_id}/timestamp`, and `/audio/reciters/{reciter_id}/lookup`.\n These IDs are not interchangeable with ayah-by-ayah recitation IDs from `/resources/recitations`.\n\nImplementation Requirements:\n1. Build the request URL: {baseUrl}/resources/chapter_reciters?{queryParams}\n2. Inject both required headers on every request\n3. Handle errors safely:\n - 401: Token expired → re-request token and retry once\n - 403: Access denied → check client credentials\n - 429: Rate limited → implement exponential backoff\n\nAcceptance Checklist:\n- [ ] Function accepts optional parameters\n- [ ] Headers x-auth-token and x-client-id are sent\n- [ ] 401/403/429 errors are handled gracefully"}],"x-qf-scopes":{"contractVersion":"content-scopes/v1","contractSha256":"0bba34fad8ac4ecc6d782eff14ae8f5cf50bac1784c832d5d1eb7d7f8be0ed36","contractStatus":"approved","routeId":"content.v4.chapter-reciters","service":"content","anyOf":["content.read","content","content.audio.read"],"legacyAnyOf":["content.read","content"],"granularAnyOf":["content.audio.read"],"deprecatedForNewClients":["content.read","content"],"quotaBuckets":["content.read","content"],"rateLimitPolicyId":"preserve-existing-content-read-policy","responseBoundary":"endpoint-family-not-data-isolation","transport":{"note":"Both headers are required together. These are not OAuth2 bearer credentials.","headers":["x-auth-token","x-client-id"]}},"extensions":[{"key":"x-code-samples","value":[{"lang":"javascript","label":"Node.js","source":"// List of Chapter Reciters\nconst axios = require('axios');\n\nconst API_BASE_URL = 'https://apis.quran.foundation/content/api/v4';\nconst ACCESS_TOKEN = '';\nconst CLIENT_ID = '';\n\nasync function callApi(options = {}) {\n const response = await axios.get(\n `${API_BASE_URL}/resources/chapter_reciters`,\n {\n headers: {\n 'x-auth-token': ACCESS_TOKEN,\n 'x-client-id': CLIENT_ID\n },\n params: options\n }\n );\n return response.data;\n}\n\n// Example usage\ncallApi({\"language\":\"en\"})\n .then(data => console.log(data))\n .catch(err => console.error(err.response?.status, err.message));"},{"lang":"python","label":"Python","source":"# List of Chapter Reciters\nimport requests\n\nAPI_BASE_URL = 'https://apis.quran.foundation/content/api/v4'\nACCESS_TOKEN = ''\nCLIENT_ID = ''\n\ndef call_api(language=None):\n params = {k: v for k, v in {'language': language}.items() if v is not None}\n \n response = requests.get(\n f'{API_BASE_URL}/resources/chapter_reciters',\n headers={\n 'x-auth-token': ACCESS_TOKEN,\n 'x-client-id': CLIENT_ID\n },\n params=params\n )\n response.raise_for_status()\n return response.json()\n\n# Example usage\ntry:\n data = call_api(language=\"en\")\n print(data)\nexcept requests.HTTPError as e:\n print(f'Error {e.response.status_code}: {e}')"},{"lang":"go","label":"Go","source":"// List of Chapter Reciters\npackage main\n\nimport (\n \"fmt\"\n \"io\"\n \"net/http\"\n \"net/url\"\n)\n\nconst API_BASE_URL = \"https://apis.quran.foundation/content/api/v4\"\nconst ACCESS_TOKEN = \"\"\nconst CLIENT_ID = \"\"\n\nfunc callApi(params map[string]string) (string, error) {\n path := \"/resources/chapter_reciters\"\n endpoint := API_BASE_URL + path\n if params != nil && len(params) > 0 {\n values := url.Values{}\n for k, v := range params {\n values.Set(k, v)\n }\n endpoint = endpoint + \"?\" + values.Encode()\n }\n\n req, err := http.NewRequest(\"GET\", endpoint, nil)\n if err != nil {\n return \"\", err\n }\n req.Header.Set(\"x-auth-token\", ACCESS_TOKEN)\n req.Header.Set(\"x-client-id\", CLIENT_ID)\n\n resp, err := http.DefaultClient.Do(req)\n if err != nil {\n return \"\", err\n }\n defer resp.Body.Close()\n\n body, err := io.ReadAll(resp.Body)\n if err != nil {\n return \"\", err\n }\n return string(body), nil\n}\n\n// Example usage\nfunc main() {\n params := map[string]string{\"language\": \"en\"}\n data, err := callApi(params)\n if err != nil {\n fmt.Println(\"Error:\", err)\n return\n }\n fmt.Println(data)\n}"},{"lang":"ruby","label":"Ruby","source":"# List of Chapter Reciters\nrequire \"net/http\"\nrequire \"uri\"\n\nAPI_BASE_URL = \"https://apis.quran.foundation/content/api/v4\"\nACCESS_TOKEN = \"\"\nCLIENT_ID = \"\"\n\ndef call_api(params = {})\n path = \"/resources/chapter_reciters\"\n uri = URI(API_BASE_URL + path)\n uri.query = URI.encode_www_form(params) if params && !params.empty?\n request_class = Net::HTTP.const_get(\"Get\")\n request = request_class.new(uri)\n request[\"x-auth-token\"] = ACCESS_TOKEN\n request[\"x-client-id\"] = CLIENT_ID\n\n response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|\n http.request(request)\n end\n\n response.body\nend\n\n# Example usage\nparams = { \"language\" => \"en\" }\ndata = call_api(params)\nputs data"},{"lang":"csharp","label":"C#","source":"// List of Chapter Reciters\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Net.Http;\nusing System.Threading.Tasks;\n\nconst string API_BASE_URL = \"https://apis.quran.foundation/content/api/v4\";\nconst string ACCESS_TOKEN = \"\";\nconst string CLIENT_ID = \"\";\n\nstatic async Task CallApiAsync(Dictionary query = null)\n{\n var path = $@\"/resources/chapter_reciters\";\n var url = API_BASE_URL + path;\n if (query != null && query.Count > 0)\n {\n var queryString = string.Join(\"&\", query.Select(kvp =>\n $\"{Uri.EscapeDataString(kvp.Key)}={Uri.EscapeDataString(kvp.Value)}\"));\n url = $\"{url}?{queryString}\";\n }\n using var client = new HttpClient();\n using var request = new HttpRequestMessage(new HttpMethod(\"GET\"), url);\n request.Headers.Add(\"x-auth-token\", ACCESS_TOKEN);\n request.Headers.Add(\"x-client-id\", CLIENT_ID);\n\n using var response = await client.SendAsync(request);\n response.EnsureSuccessStatusCode();\n return await response.Content.ReadAsStringAsync();\n}\n\n// Example usage\nvar query = new Dictionary { {\"language\", \"en\"} };\nvar data = await CallApiAsync(query);\nConsole.WriteLine(data);"},{"lang":"php","label":"PHP","source":"# List of Chapter Reciters\n';\nconst CLIENT_ID = '';\n\nfunction callApi($params = []) {\n $path = \"/resources/chapter_reciters\";\n $url = API_BASE_URL . $path;\n if (!empty($params)) {\n $url .= '?' . http_build_query($params);\n }\n $ch = curl_init($url);\n curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);\n curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');\n curl_setopt($ch, CURLOPT_HTTPHEADER, [\n 'x-auth-token: ' . ACCESS_TOKEN,\n 'x-client-id: ' . CLIENT_ID\n ]);\n\n $response = curl_exec($ch);\n if ($response === false) {\n throw new Exception(curl_error($ch));\n }\n curl_close($ch);\n return $response;\n}\n\n// Example usage\n$params = ['language' => 'en'];\n$data = callApi($params);\necho $data;\n?>"},{"lang":"java","label":"Java","source":"// List of Chapter Reciters\nimport java.io.IOException;\nimport java.util.HashMap;\nimport java.util.Map;\nimport okhttp3.HttpUrl;\nimport okhttp3.OkHttpClient;\nimport okhttp3.Request;\nimport okhttp3.RequestBody;\nimport okhttp3.Response;\n\npublic class Main {\n private static final String API_BASE_URL = \"https://apis.quran.foundation/content/api/v4\";\n private static final String ACCESS_TOKEN = \"\";\n private static final String CLIENT_ID = \"\";\n\n public static String callApi(Map params) throws IOException {\n String path = \"/resources/chapter_reciters\";\n HttpUrl.Builder urlBuilder = HttpUrl.parse(API_BASE_URL + path).newBuilder();\n if (params != null) {\n for (Map.Entry entry : params.entrySet()) {\n urlBuilder.addQueryParameter(entry.getKey(), entry.getValue());\n }\n }\n String method = \"GET\";\n RequestBody requestBody = method.equals(\"GET\") ? null : RequestBody.create(new byte[0]);\n Request request = new Request.Builder()\n .url(urlBuilder.build())\n .addHeader(\"x-auth-token\", ACCESS_TOKEN)\n .addHeader(\"x-client-id\", CLIENT_ID)\n .method(method, requestBody)\n .build();\n\n OkHttpClient client = new OkHttpClient();\n Response response = client.newCall(request).execute();\n return response.body().string();\n }\n\n public static void main(String[] args) throws Exception {\n Map params = new HashMap<>();\n params.put(\"language\", \"en\");\n String data = callApi(params);\n System.out.println(data);\n }\n}"},{"lang":"powershell","label":"PowerShell","source":"# List of Chapter Reciters\n$API_BASE_URL = \"https://apis.quran.foundation/content/api/v4\"\n$ACCESS_TOKEN = \"\"\n$CLIENT_ID = \"\"\n\nfunction Call-Api([hashtable]$params = @{}) {\n $path = \"/resources/chapter_reciters\"\n $url = \"$API_BASE_URL$path\"\n if ($params.Count -gt 0) {\n $query = ($params.GetEnumerator() | ForEach-Object {\n \"$($_.Key)=$([System.Uri]::EscapeDataString([string]$_.Value))\"\n }) -join \"&\"\n $url = \"$url?$query\"\n }\n $headers = @{\n \"x-auth-token\" = $ACCESS_TOKEN\n \"x-client-id\" = $CLIENT_ID\n }\n\n Invoke-RestMethod -Method GET -Uri $url -Headers $headers\n}\n\n# Example usage\n$params = @{ language = \"en\" }\n$data = Call-Api($params)\nWrite-Output $data"},{"lang":"bash","label":"cURL","source":"# List of Chapter Reciters\ncurl -X GET \\\n 'https://apis.quran.foundation/content/api/v4/resources/chapter_reciters?language=en' \\\n -H 'x-auth-token: ' \\\n -H 'x-client-id: '"},{"lang":"text","label":"🤖 AI Prompt","source":"Implement a function to list of chapter reciters using the Quran Foundation API.\n\nEndpoint: GET /resources/chapter_reciters\nBase URL: https://apis.quran.foundation/content/api/v4\n\nRequired Headers (copy exactly):\n x-auth-token: \n x-client-id: \nOptional Query Parameters:\n language: Name of reciters in specific language. Will fallback to English if we don't have names in specific language.\n\nNotes:\n This endpoint returns chapter-reciter IDs.\n Use these IDs with `/chapter_recitations/{reciter_id}`, `/chapter_recitations/{reciter_id}/{chapter_number}`, `/audio/reciters/{reciter_id}/timestamp`, and `/audio/reciters/{reciter_id}/lookup`.\n These IDs are not interchangeable with ayah-by-ayah recitation IDs from `/resources/recitations`.\n\nImplementation Requirements:\n1. Build the request URL: {baseUrl}/resources/chapter_reciters?{queryParams}\n2. Inject both required headers on every request\n3. Handle errors safely:\n - 401: Token expired → re-request token and retry once\n - 403: Access denied → check client credentials\n - 429: Rate limited → implement exponential backoff\n\nAcceptance Checklist:\n- [ ] Function accepts optional parameters\n- [ ] Headers x-auth-token and x-client-id are sent\n- [ ] 401/403/429 errors are handled gracefully"}]},{"key":"x-qf-scopes","value":{"contractVersion":"content-scopes/v1","contractSha256":"0bba34fad8ac4ecc6d782eff14ae8f5cf50bac1784c832d5d1eb7d7f8be0ed36","contractStatus":"approved","routeId":"content.v4.chapter-reciters","service":"content","anyOf":["content.read","content","content.audio.read"],"legacyAnyOf":["content.read","content"],"granularAnyOf":["content.audio.read"],"deprecatedForNewClients":["content.read","content"],"quotaBuckets":["content.read","content"],"rateLimitPolicyId":"preserve-existing-content-read-policy","responseBoundary":"endpoint-family-not-data-isolation","transport":{"note":"Both headers are required together. These are not OAuth2 bearer credentials.","headers":["x-auth-token","x-client-id"]}}}],"method":"get","path":"/resources/chapter_reciters","servers":[{"url":"https://apis-prelive.quran.foundation/content/api/v4","description":"Pre-production Server — testing and development only; Quran content is limited to Al-Fatihah (surah 1) and Al-Baqarah (surah 2)."},{"url":"https://apis.quran.foundation/content/api/v4","description":"Production Server"}],"security":[{"x-auth-token":[],"x-client-id":[]}],"securitySchemes":{"x-auth-token":{"type":"apiKey","description":"The access token required for accessing the endpoints.","name":"x-auth-token","in":"header"},"x-client-id":{"type":"apiKey","description":"Your client Id","name":"x-client-id","in":"header"}},"info":{"title":"Content APIs","description":"Quran Foundation Content APIs offer programmatic access to the Quran's core content like chapters, verses, recitations, translations, and more, distinct from user-specific data like notes and bookmarks provided by [User-related APIs](/docs/category/user-related-apis).\n\n:::note Prelive Content API limitation\nThe prelive environment is for testing and development only. Its Quran content dataset includes only Al-Fatihah (surah 1) and Al-Baqarah (surah 2). Test content requests using these surahs. For the complete Quran dataset, use the production environment after production access is approved.\n:::\n\n:::important Integrity of Translations\nPlease **disable any automatic browser-translation features** (e.g. Google-Translate-in-Chrome) when displaying text returned by the *Translations* endpoints. \nRe-translating an already vetted Quranic translation can introduce serious semantic errors.\n:::\n\n ## How to get access \n\n We are using OAuth2 flows to authenticate and authorize requests. To get started, you need to [get an access token](/docs/tutorials/oidc/getting-started-with-oauth2#obtaining-oauth-20-client-credentials) to make requests to our APIs. Since the APIs are not user-related, you will need to use the `client_credentials` grant type and [`content` scope](/docs/user_related_apis_versioned/scopes#content) when sending a request to [The OAuth 2.0 Token Endpoint](/docs/oauth2_apis_versioned/oauth-2-token-exchange) to get the access token. \n\n```mermaid\nsequenceDiagram\n participant App as Your App\n participant Auth as Quran Foundation
Authorization Server\n participant API as Quran Foundation
Resources Server\n\n App->>Auth: Request Token with Client Credentials\n Auth-->>App: Token Response (access_token)\n App->>API: Use token to call API\n API-->>App: Requested resource\n\n Note over App,Auth: Access token expires (1 hour)\n\n App->>Auth: Re-issue access_token using client_credentials\n Auth-->>App: New access_token\n```\n\n After getting a valid access token, each request to get resources will have to include 2 headers mentioned below: `x-auth-token` and `x-client-id`. This spec also includes a small subset of Quran Reflect post-read endpoints that are compatible with the `client_credentials` grant. These operations still require `x-auth-token` and `x-client-id`, but they do not use the `content` scope. Use `post.read` for `/quran-reflect/v1/posts/feed`, `/quran-reflect/v1/posts/{id}`, and `/quran-reflect/v1/posts/user-posts/{id}`. Use `comment.read` for `/quran-reflect/v1/posts/{id}/comments` and `/quran-reflect/v1/posts/{id}/all-comments`. These are Quran Reflect gateway endpoints, not `/content/api/v4/...` endpoints. The Qira'at endpoints under `/content/api/v4/qiraat/...` are scope-gated: they require the `qiraat.read` scope (or the parent `qiraat` scope) instead of `content`, so request the Qira'at scope your client has been approved for when you [get an access token](/docs/user_related_apis_versioned/scopes#qiraat).","version":"v4"},"postman":{"name":"List of Chapter Reciters","description":{"content":"Get list of available chapter reciters. Use these IDs with `/chapter_recitations/{reciter_id}`, `/chapter_recitations/{reciter_id}/{chapter_number}`, `/audio/reciters/{reciter_id}/timestamp`, and `/audio/reciters/{reciter_id}/lookup`. These IDs are not interchangeable with ayah-by-ayah recitation IDs from `/resources/recitations`.","type":"text/plain"},"url":{"path":["resources","chapter_reciters"],"host":["{{baseUrl}}"],"query":[{"disabled":false,"description":{"content":"Name of reciters in specific language. Will fallback to English if we don't have names in specific language.","type":"text/plain"},"key":"language","value":""}],"variable":[]},"header":[{"key":"Accept","value":"application/json"}],"method":"GET"}} sidebar_class_name: "get api-method" info_path: docs/content_apis_versioned/content-apis custom_edit_url: null @@ -31,7 +31,7 @@ Get list of available chapter reciters. Use these IDs with `/chapter_recitations Successful response -
Schema
    reciters object[] required
  • Array [
  • style object required
    qirat object required
    translated_name object nullable
  • ]

Successful response

+
Schema
    reciters object[] required
  • Array [
  • style object required
    qirat object required
    translated_name object nullable
  • ]

Successful response

Will be returned when the request is invalid e.g. request is missing required headers or with invalid query parameters. @@ -41,7 +41,7 @@ Will be returned when the request is unauthorized.
Schema
-Forbidden error. Can either be due to access token not being passed, having been expired or the caller trying to access a resource without enough permissions. +The request is forbidden, for example because a valid access token lacks the required scope or the client lacks permission.
Schema
diff --git a/openAPI/content/v4.json b/openAPI/content/v4.json index c5d49baa..b0713ce3 100644 --- a/openAPI/content/v4.json +++ b/openAPI/content/v4.json @@ -10353,8 +10353,10 @@ "value": { "reciters": [ { - "id": 3, + "id": 4, + "reciter_id": 3, "name": "Abu Bakr al-Shatri", + "beta": false, "style": { "name": "Murattal", "language_name": "english" @@ -22116,7 +22118,8 @@ "chapter_id": 1, "file_size": 710784, "format": "mp3", - "audio_url": "https://download.quranicaudio.com/qdc/abu_bakr_shatri/murattal/1.mp3" + "audio_url": "https://download.quranicaudio.com/qdc/abu_bakr_shatri/murattal/1.mp3", + "duration": 53000 } } }, @@ -22129,6 +22132,7 @@ "file_size": 710784, "format": "mp3", "audio_url": "https://download.quranicaudio.com/qdc/abu_bakr_shatri/murattal/1.mp3", + "duration": 53000, "timestamps": [ { "verse_key": "1:1", @@ -26381,6 +26385,12 @@ "format": "uri", "example": "https://download.quranicaudio.com/qdc/abu_bakr_shatri/murattal/1.mp3" }, + "duration": { + "type": "integer", + "nullable": true, + "description": "Length of the audio file in milliseconds. `null` when the length is unknown.", + "example": 53000 + }, "timestamps": { "type": "array", "description": "Present when timing data is available. If `segments=true`, each item may include a `segments` array.", @@ -27279,6 +27289,11 @@ "audio_url": { "type": "string", "description": "The audio file's url" + }, + "duration": { + "type": "integer", + "nullable": true, + "description": "Length of the audio file in milliseconds. `null` when the length is unknown." } }, "example": { @@ -27302,18 +27317,29 @@ "id", "name", "style", - "qirat" + "qirat", + "reciter_id", + "beta" ], "type": "object", "properties": { "id": { "type": "integer", - "description": "Reciter ID" + "description": "Chapter-reciter ID. Use it as `reciter_id` in [/chapter_recitations/{reciter_id}](/docs/content_apis_versioned/chapter-reciter-audio-files)." + }, + "reciter_id": { + "type": "integer", + "nullable": true, + "description": "ID of the person reciting. Several chapter reciters (for example, Murattal and Mujawwad styles of the same reciter) can share one `reciter_id`." }, "name": { "type": "string", "description": "Name of reciter in English" }, + "beta": { + "type": "boolean", + "description": "`true` when Quran.com marks the recitation as beta." + }, "style": { "type": "object", "properties": { @@ -27354,8 +27380,10 @@ } }, "example": { - "id": 3, + "id": 4, + "reciter_id": 3, "name": "Abu Bakr al-Shatri", + "beta": false, "style": { "name": "Murattal", "language_name": "english"