The YouVersion Bible API uses standard HTTP status codes to indicate the success or failure of requests. This page documents the status codes the API returns, the response body shape you get with each, and how to handle them.
Status code definitions link to RFC 9110, the HTTP Semantics specification, and are registered in the IANA HTTP Status Code Registry.
HTTP Status Codes
2xx Success
| Code | Meaning | When you see it |
|---|---|---|
| 200 OK | Request succeeded | Standard successful response |
| 201 Created | Resource created | After a successful POST, for example creating a highlight |
| 204 No Content | Succeeded, nothing to return | No data matches your parameters. This is not an error |
| 206 Partial Content | Part of the resource | You sent a Range header. Responses advertise Accept-Ranges: bytes |
3xx Redirection
| Code | Meaning | When you see it |
|---|---|---|
| 301 Moved Permanently | Resource has a canonical URL | A non-canonical language code redirects to its canonical form, e.g. /v1/languages/cmn to /v1/languages/zh. Follow the Location header |
| 303 See Other | Continue at another URL | The consent redirect back to your callback URL. See Sign In APIs |
| 304 Not Modified | Your cached copy is current | You sent If-None-Match or If-Modified-Since and nothing changed. The body is empty, so reuse what you have |
| 308 Permanent Redirect | Resource has a new URL | Plain HTTP is redirected to HTTPS. Follow the Location header |
4xx Client Errors
| Code | Meaning | When you see it |
|---|---|---|
| 400 Bad Request | Invalid parameters or request format | A parameter value the API cannot accept |
| 401 Unauthorized | Missing or invalid App Key | No X-YVP-App-Key header, or the key is not recognized |
| 403 Forbidden | Key is valid but not permitted | Your App Key cannot access this content or endpoint |
| 404 Not Found | Resource does not exist | Unknown Bible, book, chapter, or verse |
| 405 Method Not Allowed | Wrong method for this path | The path exists but not for that verb, for example POST /v1/bibles. OPTIONS is also unsupported, so browser preflights fail |
| 409 Conflict | The resource already exists | Creating a highlight the user already has. Treat it as success |
| 412 Precondition Failed | The app behind your App Key is archived or unknown | The key still authenticates, but the app it belongs to has been archived or removed. Check the app's status in the Developer Portal |
| 422 Unprocessable Content | Request understood but parameters failed validation | A required parameter is missing or malformed |
| 429 Too Many Requests | Rate limit exceeded | You have exceeded your App Key's request allowance |
5xx Server Errors
| Code | Meaning | When you see it |
|---|---|---|
| 500 Internal Server Error | Unexpected server error | Retry with backoff |
| 502 Bad Gateway | An upstream service failed | Retry with backoff |
| 503 Service Unavailable | Temporarily unavailable | Retry with backoff |
| 504 Gateway Timeout | An upstream service did not answer in time | Most often a large passage or catalog request. Retry with backoff |
Response Body Shapes
Errors do not all share one body shape, because they can be produced at different layers. Parse defensively rather than assuming a single format.
Most API errors return a JSON object with a message field:
Code
Authentication errors are produced at the API gateway before your request reaches the API, and use a fault envelope:
Code
Parameter validation errors return a detail array, one entry per invalid parameter:
Code
Rate limit errors are returned at the edge as text/plain, not JSON:
Code
Calling response.json() on a 429 will throw. Check the status code before parsing.
Common Error Scenarios
Authentication Errors
Status Code: 401 Unauthorized
Cause: Missing or invalid X-YVP-App-Key header.
Browser note: today this response is generated at the API gateway, ahead of the application, and
does not include Access-Control-* headers, so a browser fetch() rejects with a TypeError rather
than exposing response.status. Server-side callers see the 401 normally.
Example Response (header missing entirely):
Code
Example Response (header present, key not recognized):
Code
Solution: Include a valid App Key in the X-YVP-App-Key header with every request. The two errorcode values above distinguish a missing header from an unrecognized key.
Forbidden
Status Code: 403 Forbidden
Cause: Your App Key is valid, but it is not permitted to do what the request asks. This is distinct from a 401, where the key itself is not recognized. There are three common causes:
- The Bible is not licensed to your app. Each Bible is available only to apps whose organization has accepted the relevant publisher license. Requesting a Bible outside that set is forbidden even though the Bible exists.
- The endpoint is not enabled for your App Key. Not every App Key is authorized for every API.
- A required user permission was not granted. Endpoints acting on user data, such as highlights, need the signed-in user to have granted that permission. Without the grant the request is forbidden even with a valid key and token.
Example Response (requesting a passage from a Bible your app is not licensed for):
Code
The number in the message is the Bible ID that was refused.
Metadata is not gated the same way as content. GET /v1/bibles/{bible_id} returns 200 with the version's title, abbreviation, and copyright even when your app is not licensed for it. Only the content endpoints, such as GET /v1/bibles/{bible_id}/passages/{usfm}, return 403. A Bible appearing in a metadata response is therefore not a guarantee that you can read its text.
Solution: Check which Bibles your key can reach by calling GET /v1/bibles?language_ranges[]=en without all_available, which returns only what your app is licensed for. Compare that against GET /v1/bibles?all_available=true&language_ranges[]=en, which returns the full platform catalog. language_ranges[] is required on both; omitting it returns a 422. If the Bible appears only in the second list, your organization needs to accept that publisher's license. For user data endpoints, confirm the user completed the permission grant during sign in.
A common cause is a hardcoded default Bible ID that your App Key is not licensed for. Prefer selecting a Bible from your app-scoped GET /v1/bibles?language_ranges[]=en response rather than assuming an ID is available.
Invalid Parameters
Status Code: 400 Bad Request
Cause: A parameter value the API cannot accept, such as a language_ranges[] value containing
characters outside letters, numbers, hyphens, and *.
Example Response:
Code
A parameter of the wrong type, or a required parameter left out, is a 422 rather than a 400. See Failed Validation below.
Failed Validation
Status Code: 422 Unprocessable Content
Cause: The request was well formed, but a parameter failed validation. Most often a required parameter is missing, or a value is outside its allowed range.
Example Response:
Code
Solution: Read loc to find which parameter failed and msg for the reason. The array contains one entry per failing parameter, so a single response can report several problems at once.
Resource Not Found
Status Code: 404 Not Found
Cause: The requested resource does not exist.
Example Response:
Code
Common Scenarios:
- Bible version ID doesn't exist
- Book USFM identifier is invalid
- Chapter number exceeds the book's chapter count
- Verse number exceeds the chapter's verse count
A 404 can also mean the endpoint path itself is not recognized. If a request returns 404 with an empty body rather than a JSON message, check the URL before checking your parameters.
Rate Limited
Status Code: 429 Too Many Requests
Cause: You have exceeded the request allowance for your App Key. Limits are applied per App Key at the edge.
Response Headers:
Retry-After: seconds to wait before retrying
Example Response (Content-Type: text/plain):
Code
Solution: Respect the Retry-After header rather than retrying immediately, and use exponential backoff for repeated failures. Because this response is plain text, guard your parsing with a status check before calling response.json().
Browser note: today this response is built at the edge with only Retry-After and a body, so it
does not include Access-Control-* headers. A browser fetch() rejects with a TypeError, and
neither the status nor Retry-After is readable. Server-side callers see both normally.
To reduce the chance of hitting the limit, cache responses where you can and avoid fanning out one request per Bible version when a single call would do.
No Content Available
Status Code: 204 No Content
Cause: Request was successful but no data matches the criteria.
Example: Requesting Bible versions for a language that has no available translations.
Solution: This is not an error. It is a valid response indicating no content is available for the given parameters. A 204 has no response body, so do not try to parse one.
Error Handling Examples
JavaScript (Fetch API)
The samples below request /v1/bibles?language_ranges[]=en. language_ranges[] is required on
that endpoint, so the bare path returns a 422 rather than the success these examples are meant
to show.
Code
Python (Requests)
Code
cURL
Code
Two things worth copying from this. The 204 case comes before the general 2* case, because it
has no body to print. And -L is deliberately absent: with it, curl follows the redirect and
%{http_code} reports the final hop, so /v1/languages/cmn would report 200 and you would never
see the 301. Add -L once you no longer care about the redirect itself.
The 403 and 404 branches print the body rather than a fixed string, because both codes have more
than one cause and only the message distinguishes them.
Best Practices for Error Handling
- Always check status codes: Don't assume requests will succeed
- Check the status before parsing: 204 has no body and 429 is plain text, so parsing either as JSON will throw
- Handle 401 and 403 differently: 401 means the key is not recognized, 403 means it is recognized but not permitted. Retrying with the same key fixes neither
- Implement retry logic: For transient errors (5xx) and for 429, honoring
Retry-After - Log error details: Include status codes and error messages in logs
- Provide user-friendly messages: Translate technical errors for end users
- Validate parameters: Check parameters before making requests
- Use appropriate timeouts: Don't let requests hang indefinitely
Testing Error Scenarios
You can test error handling by:
- Invalid App Key: Use a fake App Key to test 401 responses
- Unlicensed Bible: Request a Bible ID that appears in
GET /v1/bibles?all_available=true&language_ranges[]=enbut not in your app-scopedGET /v1/bibles?language_ranges[]=ento test 403 responses - Invalid Bible ID: Use a non-existent Bible ID (e.g. 99999999) to test 404 responses
- Missing required parameter: Omit a required query parameter to test 422 responses
- Invalid parameters: Use malformed query parameters to test 400 responses
- Network issues: Disconnect from the internet to test connection errors
Getting Help
If you encounter errors that aren't documented here or need clarification:
- Check the API Reference for endpoint-specific error information
- Review the Authentication guide
- Contact the YouVersion Platform Team for support