Used by thousands of students worldwide - help us reach 150 members
Books
/booksBrowse, search, create and edit books. A book is a classical text stored as an ordered array of bilingual lines (Arabic, English, commentary, root words) embedded in the book document. Most error responses in this group are plain-text bodies rather than JSON.
/books/searchSearch books and linesGET/booksList public booksGET/books/adminbooksList all books with owner infoGET/books/mybooksList my booksGET/books/categoriesList categories of public booksGET/books/mybooks/categoriesList categories of my booksPOST/booksCreate a bookGET/books/:bookIdGet a book with its linesGET/books/:bookId/linesList lines in a bookPOST/books/:bookId/linesAdd a line to a bookPOST/books/:bookId/lines/bulkAdd multiple lines to a bookGET/books/:bookId/lines/:lineIdGet a single linePUT/books/:bookId/lines/:lineIdUpdate a linePOST/books/:bookId/lines/:lineId/translateAuto-translate a line to EnglishPOST/books/:bookId/translateAuto-translate Arabic text to EnglishDELETE/books/:bookId/lines/:lineIdDelete a linePUT/books/:bookId/lines/:index/moveMove a line to a new positionDELETE/books/:bookIdDelete a bookPUT/books/:bookIdUpdate book detailsSearch books and lines
Full-text search across book titles, authors and line content (Arabic, English, commentary, rootwords). Results are filtered by what the caller may see: anonymous callers only get books with visibility "public" and accessModel "public"; logged-in members additionally get books they own or contribute to; editors and admins get every non-deleted book. An invalid or malformed token is silently treated as anonymous. When Elasticsearch is enabled the top 20 hits are returned in relevance order; otherwise a case-insensitive MongoDB regex search is used with no result limit. Each book lists the lines that matched along with a short excerpt around the match; books that matched only on title/author have an empty matchingLines array.
Query parameters
qrequiredstring | Search text. In the MongoDB fallback it is used as a case-insensitive regular expression. |
Errors
400Bad Request: Missing query parameter (q was not provided)500Internal Server Error
curl -X GET "https://app.ummahspot.com/books/search" \
-H "Authorization: Bearer $SHARH_TOKEN"{
"books": [
{
"id": "64f1c2a9e4b0a1d2c3e4f567",
"title": "Al-Ajrumiyyah",
"author": "Ibn Ajurrum",
"metadata": {
"language": "English"
},
"matchingLines": [
{
"id": "64f1c2a9e4b0a1d2c3e4f570",
"excerpt": "Speech is a composed utterance that conveys a complete meaning"
}
]
}
]
}List public books
Returns every non-deleted book with visibility "public", without lines. Books gated behind a creator subscription (accessModel "creator_subscription") are still listed so they remain discoverable. All filters are case-insensitive partial (regex) matches. There is no pagination; the full list is returned.
Query parameters
titlestring | Filter by title (partial, case-insensitive). |
categorystring | Filter by category (partial, case-insensitive). |
authorstring | Filter by author (partial, case-insensitive). |
progressstring | Filter by translation progress. Stored values: "In Progress", "Near Complete", "Complete". |
difficultystring | Filter by difficulty. Stored values: "Beginner", "Intermediate", "Advanced". |
translatorstring | Filter by translator (partial, case-insensitive). |
languagestring | Filter by metadata.language (partial, case-insensitive). |
sortstring | Sort order. One of title_asc, title_desc, date_asc, date_desc (date = lastUpdated). Unknown values fall back to date_desc.Default: date_desc |
Errors
500Internal Server Error (1)
curl -X GET "https://app.ummahspot.com/books"{
"books": [
{
"id": "64f1c2a9e4b0a1d2c3e4f567",
"title": "Al-Ajrumiyyah",
"author": "Ibn Ajurrum",
"metadata": {
"language": "English"
},
"lastUpdated": "2026-08-30T14:12:05.120Z",
"translator": "Unknown",
"progress": "Complete",
"category": "Nahw",
"description": "A foundational primer in Arabic grammar.",
"difficulty": "Beginner",
"visibility": "public",
"accessModel": "public",
"requiredSubscriptionTier": null
}
]
}List all books with owner info
Returns every non-deleted book regardless of visibility (public and private), without lines, each with its owner's id, username and email. Intended for editorial/admin dashboards. No pagination.
Query parameters
titlestring | Filter by title (partial, case-insensitive). |
categorystring | Filter by category (partial, case-insensitive). |
authorstring | Filter by author (partial, case-insensitive). |
sortstring | Sort order. One of title_asc, title_desc, date_asc, date_desc (date = lastUpdated). Unknown values fall back to date_desc.Default: date_desc |
Errors
401Unauthorized: No token provided403Forbidden: Invalid token, or the user does not have one of the allowed roles404User not found (the token's user no longer exists)500Internal Server Error (1)
curl -X GET "https://app.ummahspot.com/books/adminbooks" \
-H "Authorization: Bearer $SHARH_TOKEN"{
"books": [
{
"id": "64f1c2a9e4b0a1d2c3e4f567",
"title": "Al-Ajrumiyyah",
"author": "Ibn Ajurrum",
"metadata": {
"language": "English"
},
"lastUpdated": "2026-08-30T14:12:05.120Z",
"translator": "Unknown",
"progress": "Complete",
"category": "Nahw",
"description": "A foundational primer in Arabic grammar.",
"visibility": "private",
"accessModel": "public",
"requiredSubscriptionTier": null,
"owner": {
"id": "64e0b7f2a1c3d4e5f6a7b8c9",
"username": "abdullah",
"email": "abdullah@example.com"
}
}
]
}List my books
Returns the non-deleted books where the authenticated user is the owner or a contributor, of any visibility, without lines. No pagination.
Query parameters
titlestring | Filter by title (partial, case-insensitive). |
categorystring | Filter by category (partial, case-insensitive). |
authorstring | Filter by author (partial, case-insensitive). |
sortstring | Sort order. One of title_asc, title_desc, date_asc, date_desc (date = lastUpdated). Unknown values fall back to date_desc.Default: date_desc |
Errors
401Unauthorized: No token provided403Forbidden: Invalid token, or the user does not have one of the allowed roles404User not found (the token's user no longer exists)500Internal Server Error (1)
curl -X GET "https://app.ummahspot.com/books/mybooks" \
-H "Authorization: Bearer $SHARH_TOKEN"{
"books": [
{
"id": "64f1c2a9e4b0a1d2c3e4f567",
"title": "Al-Ajrumiyyah",
"author": "Ibn Ajurrum",
"metadata": {
"language": "English"
},
"translator": "Unknown",
"progress": "In Progress",
"category": "Nahw",
"visibility": "private",
"accessModel": "public",
"requiredSubscriptionTier": null
}
]
}List categories of public books
Returns the distinct, non-empty category values used by non-deleted public books, sorted alphabetically.
Errors
500Internal Server Error
curl -X GET "https://app.ummahspot.com/books/categories"{
"categories": [
"Aqidah",
"Fiqh",
"Nahw"
]
}List categories of my books
Returns the distinct, non-empty category values used by non-deleted books the authenticated user owns or contributes to, sorted alphabetically.
Errors
401Unauthorized: No token provided403Forbidden: Invalid token, or the user does not have one of the allowed roles404User not found (the token's user no longer exists)500Internal Server Error
curl -X GET "https://app.ummahspot.com/books/mybooks/categories" \
-H "Authorization: Bearer $SHARH_TOKEN"{
"categories": [
"Nahw",
"Uncategorized"
]
}Create a book
Creates a new book owned by the authenticated user. The book fields are sent inside a "newBook" object, which is passed to the Book model as-is (so any Book schema field may be supplied); owner is always overwritten with the caller. Titles must be unique across all books. Schema defaults apply to omitted fields (visibility "private", accessModel "public", category "Uncategorized", translator "Unknown", progress "In Progress", difficulty "Beginner"). The "owner" field of the response is a minimal summary of the authenticated caller: { id, username, email }.
Body parameters
newBookrequiredobject | The book to create. |
newBook.titlerequiredstring | Book title. Must not match the title of an existing book. |
newBook.authorrequiredstring | Author of the original text. |
newBook.metadataobject | Free-form metadata object (e.g. { "language": "English" }). |
newBook.linesarray | Initial lines. Each item: { Arabic, English, commentary, rootwords } (all strings). |
newBook.categorystring | Category label.Default: Uncategorized |
newBook.translatorstring | Translator name.Default: Unknown |
newBook.descriptionstring | Book description.Default: "" |
newBook.progressstring | One of "In Progress", "Near Complete", "Complete".Default: In Progress |
newBook.difficultystring | One of "Beginner", "Intermediate", "Advanced".Default: Beginner |
newBook.visibilitystring | One of "private", "public".Default: private |
newBook.accessModelstring | One of "public", "creator_subscription".Default: public |
newBook.requiredSubscriptionTiernumber | Creator subscription tier (1-3) required to read the book when accessModel is "creator_subscription".Default: null |
Errors
400Bad Request: Missing required fields (title or author), or a book with the same title already exists401Unauthorized: No token provided403Forbidden: Invalid token, or the user does not have one of the allowed roles404User not found (the token's user no longer exists)500Internal Server Error (2) — includes schema validation failures such as an invalid enum value
curl -X POST "https://app.ummahspot.com/books" \
-H "Authorization: Bearer $SHARH_TOKEN" \
-H "Content-Type: application/json" \
-d '{"newBook":{"title":"string","author":"string"}}'{
"id": "64f1c2a9e4b0a1d2c3e4f567",
"title": "Al-Ajrumiyyah",
"author": "Ibn Ajurrum",
"metadata": {
"language": "English"
},
"lines": [
{
"id": "64f1c2a9e4b0a1d2c3e4f570",
"Arabic": "الكلام هو اللفظ المركب المفيد بالوضع",
"English": "Speech is a composed utterance that conveys a complete meaning by convention.",
"commentary": "",
"rootwords": ""
}
],
"owner": {
"id": "64e0b7f2a1c3d4e5f6a7b8c9",
"username": "abdullah",
"email": "abdullah@example.com"
},
"category": "Nahw",
"translator": "Unknown",
"progress": "In Progress",
"difficulty": "Beginner",
"visibility": "private",
"accessModel": "public",
"requiredSubscriptionTier": null
}Get a book with its lines
Returns the full book including all lines, its editors object and a canEdit flag for the caller. What editors contains depends on the caller: callers who can edit the book (admins, the owner and contributors) get owner, contributors[] and admins[] (every platform admin) as { id, username, email }; every other caller, including anonymous ones, gets owner and contributors[] as { id, username } only — no email addresses — and admins is always an empty array. The example below shows the response for a reader who cannot edit the book (canEdit false). Public books are readable by anyone. Private books are only returned to the owner, contributors and admins — everyone else gets a 404. If the book uses accessModel "creator_subscription" with a requiredSubscriptionTier, callers who cannot edit it must hold an active subscription to the book's creator at that tier or higher, otherwise a 402 JSON body describing the required subscription is returned. An invalid token is silently treated as anonymous. Soft-deleted books return 404.
Path parameters
bookIdstring | Book ObjectId |
Errors
402Creator subscription required. JSON body: { requiresSubscription: true, message, contentType: "book", contentId, requiredSubscriptionTier, creator }404No book with the given ID exists (or it is deleted), or the book is private and the caller cannot edit it ({ "error": "Book not found." })500Internal Server Error (also returned for a malformed bookId)
curl -X GET "https://app.ummahspot.com/books/:bookId" \
-H "Authorization: Bearer $SHARH_TOKEN"{
"id": "64f1c2a9e4b0a1d2c3e4f567",
"title": "Al-Ajrumiyyah",
"author": "Ibn Ajurrum",
"visibility": "public",
"accessModel": "public",
"requiredSubscriptionTier": null,
"description": "A foundational primer in Arabic grammar.",
"metadata": {
"language": "English"
},
"difficulty": "Beginner",
"lines": [
{
"id": "64f1c2a9e4b0a1d2c3e4f570",
"Arabic": "الكلام هو اللفظ المركب المفيد بالوضع",
"English": "Speech is a composed utterance that conveys a complete meaning by convention.",
"commentary": "The author begins with the definition of kalam.",
"rootwords": "ك ل م"
}
],
"lastUpdated": "2026-08-30T14:12:05.120Z",
"editors": {
"owner": {
"id": "64e0b7f2a1c3d4e5f6a7b8c9",
"username": "abdullah"
},
"contributors": [
{
"id": "64e0b7f2a1c3d4e5f6a7b8d0",
"username": "maryam"
}
],
"admins": []
},
"translator": "Unknown",
"progress": "Complete",
"category": "Nahw",
"canEdit": false,
"creator": {
"id": "64e0b7f2a1c3d4e5f6a7b8c9",
"username": "abdullah",
"profilePicture": null,
"tagline": "",
"bio": "",
"publicationTitle": "",
"slug": "",
"coverImage": "",
"bannerText": "",
"featuredQuote": "",
"socialLinks": {
"website": "",
"x": "",
"youtube": "",
"instagram": ""
},
"creatorStatus": "none"
}
}List lines in a book
Returns the book's lines with a lighter set of book fields. Visibility rules are the same as GET /books/:bookId: private books are only visible to the owner, contributors and admins (404 otherwise), and creator-subscription books return 402 unless the caller can manage the book or holds an active subscription to the creator at the required tier. An invalid token is silently treated as anonymous. Lines are returned in book order; there is no pagination.
Path parameters
bookIdstring | Book ObjectId |
Errors
402Creator subscription required. JSON body: { requiresSubscription: true, message, contentType: "book", contentId, requiredSubscriptionTier, creator }404No book with the given ID exists (or it is deleted), or the book is private and the caller cannot manage it ({ "error": "Book not found." })500Internal Server Error (4) (also returned for a malformed bookId)
curl -X GET "https://app.ummahspot.com/books/:bookId/lines" \
-H "Authorization: Bearer $SHARH_TOKEN"{
"id": "64f1c2a9e4b0a1d2c3e4f567",
"title": "Al-Ajrumiyyah",
"author": "Ibn Ajurrum",
"metadata": {
"language": "English"
},
"lines": [
{
"id": "64f1c2a9e4b0a1d2c3e4f570",
"Arabic": "الكلام هو اللفظ المركب المفيد بالوضع",
"English": "Speech is a composed utterance that conveys a complete meaning by convention.",
"commentary": "The author begins with the definition of kalam.",
"rootwords": "ك ل م"
}
],
"category": "Nahw",
"translator": "Unknown",
"progress": "Complete",
"accessModel": "public",
"requiredSubscriptionTier": null
}Add a line to a book
Inserts a new line into the book. The caller must be the book's owner, one of its contributors, or an admin (EditGuard). If "position" is a valid index (0 to the current number of lines) the line is inserted there; otherwise it is appended. Note: the response always contains the LAST line of the book after saving, which is the new line only when it was appended.
Path parameters
bookIdstring | Book ObjectId |
Body parameters
newLinerequiredobject | The line to add: { Arabic, English, commentary, rootwords } (all optional strings). |
positionnumber | Zero-based index to insert at (0 ≤ position ≤ line count). Omitted or out of range: the line is appended. |
Errors
400Bad Request: Missing required fields (newLine not provided)401Unauthorized: No token provided403Forbidden: Invalid token, or you do not have permission to modify this book (not the owner, a contributor, or an admin)404No book with the given ID exists, or the token's user was not found500Internal Server Error (6)
curl -X POST "https://app.ummahspot.com/books/:bookId/lines" \
-H "Authorization: Bearer $SHARH_TOKEN" \
-H "Content-Type: application/json" \
-d '{"newLine":{}}'{
"id": "64f1c2a9e4b0a1d2c3e4f571",
"Arabic": "وأقسامه ثلاثة: اسم وفعل وحرف جاء لمعنى",
"English": "Its parts are three: the noun, the verb, and the particle that conveys a meaning.",
"commentary": "",
"rootwords": ""
}Add multiple lines to a book
Inserts several lines in one request. The caller must be the book's owner, one of its contributors, or an admin (EditGuard). If "position" is a valid index the lines are inserted there in order; otherwise they are appended. Note: the response contains the last N lines of the book after saving (N = newLines.length), which are the new lines only when they were appended.
Path parameters
bookIdstring | Book ObjectId |
Body parameters
newLinesrequiredarray | Non-empty array of lines, each { Arabic, English, commentary, rootwords } (all optional strings). |
positionnumber | Zero-based index to insert at (0 ≤ position ≤ line count). Omitted or out of range: the lines are appended. |
Errors
400Bad Request: newLines must be a non-empty array401Unauthorized: No token provided403Forbidden: Invalid token, or you do not have permission to modify this book (not the owner, a contributor, or an admin)404Book not found, or the token's user was not found500Internal Server Error
curl -X POST "https://app.ummahspot.com/books/:bookId/lines/bulk" \
-H "Authorization: Bearer $SHARH_TOKEN" \
-H "Content-Type: application/json" \
-d '{"newLines":[]}'[
{
"id": "64f1c2a9e4b0a1d2c3e4f571",
"Arabic": "وأقسامه ثلاثة: اسم وفعل وحرف جاء لمعنى",
"English": "Its parts are three: the noun, the verb, and the particle that conveys a meaning.",
"commentary": "",
"rootwords": ""
}
]Get a single line
Returns one line of a book by its id. Access to the parent book is gated exactly like GET /books/:bookId: lines of public books are readable by anyone, lines of private books are only returned to the owner, contributors and admins (everyone else gets a 404), and if the book uses accessModel "creator_subscription" with a requiredSubscriptionTier, callers who cannot manage it must hold an active subscription to the book's creator at that tier or higher, otherwise a 402 JSON body describing the required subscription is returned. An invalid token is silently treated as anonymous. Soft-deleted books return 404.
Path parameters
bookIdstring | Book ObjectId |
lineIdstring | Line ObjectId (the "id" of a line as returned by the lines endpoints) |
Errors
402Creator subscription required. JSON body: { requiresSubscription: true, message, contentType: "book", contentId, requiredSubscriptionTier, creator }404No book with the given ID exists or it is deleted, or no line with the given ID exists in it (plain-text body); or the book is not public and the caller is not its owner, a contributor or an admin (JSON body { "error": "Book not found" })500Internal Server Error (7) (also returned for a malformed bookId)
curl -X GET "https://app.ummahspot.com/books/:bookId/lines/:lineId" \
-H "Authorization: Bearer $SHARH_TOKEN"{
"id": "64f1c2a9e4b0a1d2c3e4f570",
"Arabic": "الكلام هو اللفظ المركب المفيد بالوضع",
"English": "Speech is a composed utterance that conveys a complete meaning by convention.",
"commentary": "The author begins with the definition of kalam.",
"rootwords": "ك ل م"
}Update a line
Updates fields of an existing line. The caller must be the book's owner, one of its contributors, or an admin (EditGuard). Only the fields present in "updatedLine" are changed. Returns the line as saved.
Path parameters
bookIdstring | Book ObjectId |
lineIdstring | Line ObjectId |
Body parameters
updatedLinerequiredobject | Fields to set on the line: any of { Arabic, English, commentary, rootwords } (strings). |
Errors
400Bad Request: Missing required fields (updatedLine not provided)401Unauthorized: No token provided403Forbidden: Invalid token, or you do not have permission to modify this book (not the owner, a contributor, or an admin)404No book with the given ID exists, no line with the given ID exists, or the token's user was not found500Internal Server Error (8)
curl -X PUT "https://app.ummahspot.com/books/:bookId/lines/:lineId" \
-H "Authorization: Bearer $SHARH_TOKEN" \
-H "Content-Type: application/json" \
-d '{"updatedLine":{}}'{
"id": "64f1c2a9e4b0a1d2c3e4f570",
"Arabic": "الكلام هو اللفظ المركب المفيد بالوضع",
"English": "Speech is a composed utterance that conveys a complete meaning by convention.",
"commentary": "Updated commentary on the definition of kalam.",
"rootwords": "ك ل م"
}Auto-translate a line to English
Generates an AI English translation of the line's Arabic text, using the book title and up to 3 preceding lines as context. The translation is returned only — the line is NOT modified; save it with PUT /books/:bookId/lines/:lineId. The caller must be the book's owner, one of its contributors, or an admin (EditGuard). Members additionally need an active Stripe subscription on the $50/month tier (or higher); editors and admins bypass the subscription check.
Path parameters
bookIdstring | Book ObjectId |
lineIdstring | Line ObjectId |
Errors
400{ "error": "no_arabic_text" } — the line has no Arabic text to translate401Unauthorized: No token provided403Invalid token or not the owner/contributor/admin of the book (plain text), or { "error": "subscription_required" } when a member lacks the $50/month subscription404{ "error": "line_not_found" }, or plain text when the book or the token's user does not exist429{ "error": "rate_limit" } — the translation provider rate limit was reached500{ "error": "subscription_check_failed" } or { "error": "translation_failed" }
curl -X POST "https://app.ummahspot.com/books/:bookId/lines/:lineId/translate" \
-H "Authorization: Bearer $SHARH_TOKEN"{
"translation": "Speech is a composed utterance that conveys a complete meaning by convention.",
"lineId": "64f1c2a9e4b0a1d2c3e4f570"
}Auto-translate Arabic text to English
Generates an AI English translation of arbitrary Arabic text in the context of a book (the book title is given to the translator), without requiring an existing line. Nothing is saved. The caller must be the book's owner, one of its contributors, or an admin (EditGuard). Members additionally need an active Stripe subscription on the $50/month tier (or higher); editors and admins bypass the subscription check.
Path parameters
bookIdstring | Book ObjectId |
Body parameters
arabicTextrequiredstring | Arabic text to translate. Must not be empty or whitespace only. |
Errors
400{ "error": "no_arabic_text" } — arabicText missing or blank401Unauthorized: No token provided403Invalid token or not the owner/contributor/admin of the book (plain text), or { "error": "subscription_required" } when a member lacks the $50/month subscription404No book with the given ID exists, or the token's user was not found429{ "error": "rate_limit" } — the translation provider rate limit was reached500{ "error": "subscription_check_failed" } or { "error": "translation_failed" }
curl -X POST "https://app.ummahspot.com/books/:bookId/translate" \
-H "Authorization: Bearer $SHARH_TOKEN" \
-H "Content-Type: application/json" \
-d '{"arabicText":"string"}'{
"translation": "Its parts are three: the noun, the verb, and the particle that conveys a meaning."
}Delete a line
Permanently removes a line from the book. The caller must be the book's owner, one of its contributors, or an admin (EditGuard). The response is a JSON string. A 200 is returned even if no line with the given id existed.
Path parameters
bookIdstring | Book ObjectId |
lineIdstring | Line ObjectId |
Errors
401Unauthorized: No token provided403Forbidden: Invalid token, or you do not have permission to modify this book (not the owner, a contributor, or an admin)404No book with the given ID exists, or the token's user was not found500Internal Server Error (9)
curl -X DELETE "https://app.ummahspot.com/books/:bookId/lines/:lineId" \
-H "Authorization: Bearer $SHARH_TOKEN""Line deleted successfully"Move a line to a new position
Reorders a line within the book by removing it from fromIndex and re-inserting it at toIndex. The caller must be the book's owner, one of its contributors, or an admin (EditGuard). The ":index" path segment is required by the route but is not read by the handler — the positions come from the request body. The response is a JSON string.
Path parameters
bookIdstring | Book ObjectId |
indexstring | Ignored by the handler; any value (conventionally the current line index). |
Body parameters
fromIndexrequirednumber | Current zero-based index of the line (0 ≤ fromIndex < line count). Parsed with parseInt. |
toIndexrequirednumber | Target zero-based index (0 ≤ toIndex < line count). Parsed with parseInt. |
Errors
400Bad Request: Indices must be integers, or Indices out of range401Unauthorized: No token provided403Forbidden: Invalid token, or you do not have permission to modify this book (not the owner, a contributor, or an admin)404No book with the given ID exists, or the token's user was not found500Internal Server Error (10)
curl -X PUT "https://app.ummahspot.com/books/:bookId/lines/:index/move" \
-H "Authorization: Bearer $SHARH_TOKEN" \
-H "Content-Type: application/json" \
-d '{"fromIndex":0,"toIndex":0}'"Line moved successfully"Delete a book
Soft-deletes a book: sets deleted=true and deletedAt, after which it no longer appears in listings, search or GET /books/:bookId. Only the book's owner or an admin may delete it — contributors may not.
Path parameters
bookIdstring | Book ObjectId |
Errors
401Unauthorized: No token provided403Forbidden: Invalid token, or you do not have permission to delete this book (not the owner or an admin)404No book with the given ID exists, or the token's user was not found500Internal Server Error
curl -X DELETE "https://app.ummahspot.com/books/:bookId" \
-H "Authorization: Bearer $SHARH_TOKEN"{
"message": "Book deleted successfully"
}Update book details
Updates a book's title and descriptive fields. The caller must be the book's owner, one of its contributors, or an admin (EditGuard). Only truthy values are applied, so a field cannot be cleared by sending an empty string. "visibility" is only applied when the caller is an admin; it is silently ignored for everyone else. The response is a JSON string, not the updated book.
Path parameters
bookIdstring | Book ObjectId |
Body parameters
titlestring | New title. |
authorstring | New author. |
metadataobject | Replaces the whole metadata object. |
categorystring | New category. |
translatorstring | New translator name. |
progressstring | One of "In Progress", "Near Complete", "Complete". |
descriptionstring | New description. |
difficultystring | One of "Beginner", "Intermediate", "Advanced". |
visibilitystring | One of "private", "public". Admins only — ignored for other callers. |
Errors
401Unauthorized: No token provided403Forbidden: Invalid token, or you do not have permission to modify this book (not the owner, a contributor, or an admin)404No book with the given ID exists, or the token's user was not found500Internal Server Error (11) — includes schema validation failures such as an invalid enum value
curl -X PUT "https://app.ummahspot.com/books/:bookId" \
-H "Authorization: Bearer $SHARH_TOKEN" \
-H "Content-Type: application/json" \
-d '{"title":"string"}'"Book updated successfully"