Ramadan Last 10 Nights Campaign

Used by thousands of students worldwide - help us reach 150 members

... / 150 members...
APIBooks

Books

/books

Browse, 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.

GET/books

List public books

Public

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

title
string
Filter by title (partial, case-insensitive).
category
string
Filter by category (partial, case-insensitive).
author
string
Filter by author (partial, case-insensitive).
progress
string
Filter by translation progress. Stored values: "In Progress", "Near Complete", "Complete".
difficulty
string
Filter by difficulty. Stored values: "Beginner", "Intermediate", "Advanced".
translator
string
Filter by translator (partial, case-insensitive).
language
string
Filter by metadata.language (partial, case-insensitive).
sort
string
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)
Request
curl -X GET "https://app.ummahspot.com/books"
Response · 200
{
  "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
    }
  ]
}
GET/books/adminbooks

List all books with owner info

Auth requirededitor / admin only

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

title
string
Filter by title (partial, case-insensitive).
category
string
Filter by category (partial, case-insensitive).
author
string
Filter by author (partial, case-insensitive).
sort
string
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 provided
  • 403Forbidden: Invalid token, or the user does not have one of the allowed roles
  • 404User not found (the token's user no longer exists)
  • 500Internal Server Error (1)
Request
curl -X GET "https://app.ummahspot.com/books/adminbooks" \
  -H "Authorization: Bearer $SHARH_TOKEN"
Response · 200
{
  "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"
      }
    }
  ]
}
GET/books/mybooks

List my books

Auth required

Returns the non-deleted books where the authenticated user is the owner or a contributor, of any visibility, without lines. No pagination.

Query parameters

title
string
Filter by title (partial, case-insensitive).
category
string
Filter by category (partial, case-insensitive).
author
string
Filter by author (partial, case-insensitive).
sort
string
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 provided
  • 403Forbidden: Invalid token, or the user does not have one of the allowed roles
  • 404User not found (the token's user no longer exists)
  • 500Internal Server Error (1)
Request
curl -X GET "https://app.ummahspot.com/books/mybooks" \
  -H "Authorization: Bearer $SHARH_TOKEN"
Response · 200
{
  "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
    }
  ]
}
GET/books/categories

List categories of public books

Public

Returns the distinct, non-empty category values used by non-deleted public books, sorted alphabetically.

Errors

  • 500Internal Server Error
Request
curl -X GET "https://app.ummahspot.com/books/categories"
Response · 200
{
  "categories": [
    "Aqidah",
    "Fiqh",
    "Nahw"
  ]
}
GET/books/mybooks/categories

List categories of my books

Auth required

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 provided
  • 403Forbidden: Invalid token, or the user does not have one of the allowed roles
  • 404User not found (the token's user no longer exists)
  • 500Internal Server Error
Request
curl -X GET "https://app.ummahspot.com/books/mybooks/categories" \
  -H "Authorization: Bearer $SHARH_TOKEN"
Response · 200
{
  "categories": [
    "Nahw",
    "Uncategorized"
  ]
}
POST/books

Create a book

Auth required

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

newBookrequired
object
The book to create.
newBook.titlerequired
string
Book title. Must not match the title of an existing book.
newBook.authorrequired
string
Author of the original text.
newBook.metadata
object
Free-form metadata object (e.g. { "language": "English" }).
newBook.lines
array
Initial lines. Each item: { Arabic, English, commentary, rootwords } (all strings).
newBook.category
string
Category label.Default: Uncategorized
newBook.translator
string
Translator name.Default: Unknown
newBook.description
string
Book description.Default: ""
newBook.progress
string
One of "In Progress", "Near Complete", "Complete".Default: In Progress
newBook.difficulty
string
One of "Beginner", "Intermediate", "Advanced".Default: Beginner
newBook.visibility
string
One of "private", "public".Default: private
newBook.accessModel
string
One of "public", "creator_subscription".Default: public
newBook.requiredSubscriptionTier
number
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 exists
  • 401Unauthorized: No token provided
  • 403Forbidden: Invalid token, or the user does not have one of the allowed roles
  • 404User not found (the token's user no longer exists)
  • 500Internal Server Error (2) — includes schema validation failures such as an invalid enum value
Request
curl -X POST "https://app.ummahspot.com/books" \
  -H "Authorization: Bearer $SHARH_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"newBook":{"title":"string","author":"string"}}'
Response · 201
{
  "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/books/:bookId

Get a book with its lines

Auth optional

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

bookId
string
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)
Request
curl -X GET "https://app.ummahspot.com/books/:bookId" \
  -H "Authorization: Bearer $SHARH_TOKEN"
Response · 200
{
  "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"
  }
}
GET/books/:bookId/lines

List lines in a book

Auth optional

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

bookId
string
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)
Request
curl -X GET "https://app.ummahspot.com/books/:bookId/lines" \
  -H "Authorization: Bearer $SHARH_TOKEN"
Response · 200
{
  "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
}
POST/books/:bookId/lines

Add a line to a book

Auth required

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

bookId
string
Book ObjectId

Body parameters

newLinerequired
object
The line to add: { Arabic, English, commentary, rootwords } (all optional strings).
position
number
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 provided
  • 403Forbidden: 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 found
  • 500Internal Server Error (6)
Request
curl -X POST "https://app.ummahspot.com/books/:bookId/lines" \
  -H "Authorization: Bearer $SHARH_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"newLine":{}}'
Response · 201
{
  "id": "64f1c2a9e4b0a1d2c3e4f571",
  "Arabic": "وأقسامه ثلاثة: اسم وفعل وحرف جاء لمعنى",
  "English": "Its parts are three: the noun, the verb, and the particle that conveys a meaning.",
  "commentary": "",
  "rootwords": ""
}
POST/books/:bookId/lines/bulk

Add multiple lines to a book

Auth required

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

bookId
string
Book ObjectId

Body parameters

newLinesrequired
array
Non-empty array of lines, each { Arabic, English, commentary, rootwords } (all optional strings).
position
number
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 array
  • 401Unauthorized: No token provided
  • 403Forbidden: 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 found
  • 500Internal Server Error
Request
curl -X POST "https://app.ummahspot.com/books/:bookId/lines/bulk" \
  -H "Authorization: Bearer $SHARH_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"newLines":[]}'
Response · 201
[
  {
    "id": "64f1c2a9e4b0a1d2c3e4f571",
    "Arabic": "وأقسامه ثلاثة: اسم وفعل وحرف جاء لمعنى",
    "English": "Its parts are three: the noun, the verb, and the particle that conveys a meaning.",
    "commentary": "",
    "rootwords": ""
  }
]
GET/books/:bookId/lines/:lineId

Get a single line

Auth optional

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

bookId
string
Book ObjectId
lineId
string
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)
Request
curl -X GET "https://app.ummahspot.com/books/:bookId/lines/:lineId" \
  -H "Authorization: Bearer $SHARH_TOKEN"
Response · 200
{
  "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": "ك ل م"
}
PUT/books/:bookId/lines/:lineId

Update a line

Auth required

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

bookId
string
Book ObjectId
lineId
string
Line ObjectId

Body parameters

updatedLinerequired
object
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 provided
  • 403Forbidden: 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 found
  • 500Internal Server Error (8)
Request
curl -X PUT "https://app.ummahspot.com/books/:bookId/lines/:lineId" \
  -H "Authorization: Bearer $SHARH_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"updatedLine":{}}'
Response · 200
{
  "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": "ك ل م"
}
POST/books/:bookId/lines/:lineId/translate

Auto-translate a line to English

Auth requiredSubscription required

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

bookId
string
Book ObjectId
lineId
string
Line ObjectId

Errors

  • 400{ "error": "no_arabic_text" } — the line has no Arabic text to translate
  • 401Unauthorized: No token provided
  • 403Invalid token or not the owner/contributor/admin of the book (plain text), or { "error": "subscription_required" } when a member lacks the $50/month subscription
  • 404{ "error": "line_not_found" }, or plain text when the book or the token's user does not exist
  • 429{ "error": "rate_limit" } — the translation provider rate limit was reached
  • 500{ "error": "subscription_check_failed" } or { "error": "translation_failed" }
Request
curl -X POST "https://app.ummahspot.com/books/:bookId/lines/:lineId/translate" \
  -H "Authorization: Bearer $SHARH_TOKEN"
Response · 200
{
  "translation": "Speech is a composed utterance that conveys a complete meaning by convention.",
  "lineId": "64f1c2a9e4b0a1d2c3e4f570"
}
POST/books/:bookId/translate

Auto-translate Arabic text to English

Auth requiredSubscription required

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

bookId
string
Book ObjectId

Body parameters

arabicTextrequired
string
Arabic text to translate. Must not be empty or whitespace only.

Errors

  • 400{ "error": "no_arabic_text" } — arabicText missing or blank
  • 401Unauthorized: No token provided
  • 403Invalid token or not the owner/contributor/admin of the book (plain text), or { "error": "subscription_required" } when a member lacks the $50/month subscription
  • 404No book with the given ID exists, or the token's user was not found
  • 429{ "error": "rate_limit" } — the translation provider rate limit was reached
  • 500{ "error": "subscription_check_failed" } or { "error": "translation_failed" }
Request
curl -X POST "https://app.ummahspot.com/books/:bookId/translate" \
  -H "Authorization: Bearer $SHARH_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"arabicText":"string"}'
Response · 200
{
  "translation": "Its parts are three: the noun, the verb, and the particle that conveys a meaning."
}
DELETE/books/:bookId/lines/:lineId

Delete a line

Auth required

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

bookId
string
Book ObjectId
lineId
string
Line ObjectId

Errors

  • 401Unauthorized: No token provided
  • 403Forbidden: 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 found
  • 500Internal Server Error (9)
Request
curl -X DELETE "https://app.ummahspot.com/books/:bookId/lines/:lineId" \
  -H "Authorization: Bearer $SHARH_TOKEN"
Response · 200
"Line deleted successfully"
PUT/books/:bookId/lines/:index/move

Move a line to a new position

Auth required

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

bookId
string
Book ObjectId
index
string
Ignored by the handler; any value (conventionally the current line index).

Body parameters

fromIndexrequired
number
Current zero-based index of the line (0 ≤ fromIndex < line count). Parsed with parseInt.
toIndexrequired
number
Target zero-based index (0 ≤ toIndex < line count). Parsed with parseInt.

Errors

  • 400Bad Request: Indices must be integers, or Indices out of range
  • 401Unauthorized: No token provided
  • 403Forbidden: 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 found
  • 500Internal Server Error (10)
Request
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}'
Response · 200
"Line moved successfully"
DELETE/books/:bookId

Delete a book

Auth required

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

bookId
string
Book ObjectId

Errors

  • 401Unauthorized: No token provided
  • 403Forbidden: 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 found
  • 500Internal Server Error
Request
curl -X DELETE "https://app.ummahspot.com/books/:bookId" \
  -H "Authorization: Bearer $SHARH_TOKEN"
Response · 200
{
  "message": "Book deleted successfully"
}
PUT/books/:bookId

Update book details

Auth required

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

bookId
string
Book ObjectId

Body parameters

title
string
New title.
author
string
New author.
metadata
object
Replaces the whole metadata object.
category
string
New category.
translator
string
New translator name.
progress
string
One of "In Progress", "Near Complete", "Complete".
description
string
New description.
difficulty
string
One of "Beginner", "Intermediate", "Advanced".
visibility
string
One of "private", "public". Admins only — ignored for other callers.

Errors

  • 401Unauthorized: No token provided
  • 403Forbidden: 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 found
  • 500Internal Server Error (11) — includes schema validation failures such as an invalid enum value
Request
curl -X PUT "https://app.ummahspot.com/books/:bookId" \
  -H "Authorization: Bearer $SHARH_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"title":"string"}'
Response · 200
"Book updated successfully"