Ramadan Last 10 Nights Campaign

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

... / 150 members...
APICreators

Creators

/creators

Creator monetization: applying to become a creator, managing the creator profile, Stripe Connect payouts onboarding, paid subscription tiers (1-3), gating books and notes behind a subscription tier, posting creator updates, subscribing to a creator via Stripe Checkout, and the public creator directory and creator pages.

GET/creators/monetization-settings

Get platform-wide creator monetization settings

Public

Returns the default platform fee and the Stripe processing-fee estimates used to compute creator payout breakdowns. Values come from the stored settings document, falling back to server defaults (5% platform fee, 2.9% + 30 cents Stripe estimate). Because this endpoint is not creator-specific, `customPlatformFeePercent` is always null and `usesCustomPlatformFee` is always false here.

Errors

  • 500Failed to load creator monetization settings
Request
curl -X GET "https://app.ummahspot.com/creators/monetization-settings"
Response · 200
{
  "monetization": {
    "platformFeePercent": 5,
    "stripeProcessingFeePercent": 2.9,
    "stripeProcessingFeeFixedCents": 30,
    "stripeFeeNote": "Stripe fees are estimates for standard domestic card payments and can vary based on card type, country, disputes, taxes, and other Stripe adjustments.",
    "currency": "usd",
    "creatorSharePercent": 95,
    "note": "Platform fees apply before Stripe processing fees, taxes, refunds, and disputes.",
    "stripeFeeDisclaimer": "Stripe fees are estimates for standard domestic card payments and can vary based on card type, country, disputes, taxes, and other Stripe adjustments.",
    "defaultPlatformFeePercent": 5,
    "customPlatformFeePercent": null,
    "usesCustomPlatformFee": false
  }
}
POST/creators/apply

Submit or update a creator application

Auth required

Submits an application to become a creator. If the user already has a pending application it is updated in place instead of creating a new one (the response is 201 in both cases). All text fields are trimmed. The user's `creatorProfile.status` is set to `pending` and their profile `tagline` and `bio` are overwritten with the submitted values. Users who are already approved creators are rejected. After responding, all admin users with an email address are notified by email.

Body parameters

biorequired
string
Creator bio. Must be non-empty after trimming.
tagline
string
Short creator tagline.Default: ''
audience
string
Description of the intended audience.Default: ''
sampleContent
string
Sample content or links for reviewers.Default: ''

Errors

  • 400Missing/empty `bio`, or the user is already an approved creator
  • 401No token provided
  • 403Invalid or expired token
  • 500Failed to submit creator application
Request
curl -X POST "https://app.ummahspot.com/creators/apply" \
  -H "Authorization: Bearer $SHARH_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"bio":"string"}'
Response · 201
{
  "application": {
    "_id": "66f1a2b3c4d5e6f7a8b9c0d1",
    "user": "64a1b2c3d4e5f6a7b8c9d0e1",
    "tagline": "Classical fiqh texts made approachable",
    "bio": "I have taught Shafi'i fiqh for ten years and publish annotated translations.",
    "audience": "Intermediate students of knowledge",
    "sampleContent": "https://sharhapp.com/books/64b2c3d4e5f6a7b8c9d0e1f2",
    "status": "pending",
    "reviewNotes": "",
    "reviewedAt": null,
    "reviewedBy": null,
    "createdAt": "2026-09-18T10:15:00.000Z",
    "updatedAt": "2026-09-18T10:15:00.000Z",
    "__v": 0
  }
}
GET/creators/me/dashboard

Get the current user's creator dashboard

Auth required

Returns everything needed to render the creator dashboard for the authenticated user: serialized creator profile, the raw `creatorProfile` (including Stripe Connect flags), the latest creator application (or null), effective monetization settings (honouring any per-creator platform fee override), revenue stats, all of the user's plans with active subscriber counts and payout breakdowns, subscribers, all of the user's non-deleted books and all notes with their access settings, and all creator updates (raw documents, newest first). Does not require approved-creator status. If a Stripe Connect account exists, its onboarding/charges/payouts flags are re-synced from Stripe first (sync failures are ignored). `subscribers` includes subscriptions with status active, trialing, past_due, unpaid or paused; revenue stats only count active and trialing ones. `totalSubscribers` counts active/trialing subscriptions whose period has not ended. `monthlyRecurringRevenueCents` and `grossMonthlyRecurringRevenueCents` are the same value.

Errors

  • 401No token provided
  • 403Invalid or expired token
  • 500Failed to load creator dashboard
Request
curl -X GET "https://app.ummahspot.com/creators/me/dashboard" \
  -H "Authorization: Bearer $SHARH_TOKEN"
Response · 200
{
  "creator": {
    "id": "64a1b2c3d4e5f6a7b8c9d0e1",
    "username": "ustadh_yusuf",
    "profilePicture": "https://example-bucket.s3.amazonaws.com/profile-pictures/64a1b2c3.jpg",
    "tagline": "Classical fiqh texts made approachable",
    "bio": "I have taught Shafi'i fiqh for ten years and publish annotated translations.",
    "publicationTitle": "The Fiqh Notebook",
    "slug": "fiqh-notebook",
    "coverImage": "https://example.com/cover.jpg",
    "bannerText": "New commentary every week",
    "featuredQuote": "Knowledge is a trust.",
    "socialLinks": {
      "website": "https://example.com",
      "x": "",
      "youtube": "https://youtube.com/@fiqhnotebook",
      "instagram": ""
    },
    "creatorStatus": "approved"
  },
  "creatorProfile": {
    "status": "approved",
    "tagline": "Classical fiqh texts made approachable",
    "bio": "I have taught Shafi'i fiqh for ten years and publish annotated translations.",
    "publicationTitle": "The Fiqh Notebook",
    "slug": "fiqh-notebook",
    "coverImage": "https://example.com/cover.jpg",
    "bannerText": "New commentary every week",
    "featuredQuote": "Knowledge is a trust.",
    "socialLinks": {
      "website": "https://example.com",
      "x": "",
      "youtube": "https://youtube.com/@fiqhnotebook",
      "instagram": ""
    },
    "approvedAt": "2026-08-01T09:00:00.000Z",
    "approvedBy": "64a0000000000000000000aa",
    "customPlatformFeePercent": null,
    "stripeConnectAccountId": "acct_XXXXXXXXXXXXXXXX",
    "stripeConnectOnboarded": true,
    "stripeChargesEnabled": true,
    "stripePayoutsEnabled": true
  },
  "application": {
    "_id": "66f1a2b3c4d5e6f7a8b9c0d1",
    "user": "64a1b2c3d4e5f6a7b8c9d0e1",
    "tagline": "Classical fiqh texts made approachable",
    "bio": "I have taught Shafi'i fiqh for ten years and publish annotated translations.",
    "audience": "Intermediate students of knowledge",
    "sampleContent": "",
    "status": "approved",
    "reviewNotes": "",
    "reviewedAt": "2026-08-01T09:00:00.000Z",
    "reviewedBy": "64a0000000000000000000aa",
    "createdAt": "2026-07-28T10:15:00.000Z",
    "updatedAt": "2026-08-01T09:00:00.000Z",
    "__v": 0
  },
  "monetization": {
    "platformFeePercent": 5,
    "stripeProcessingFeePercent": 2.9,
    "stripeProcessingFeeFixedCents": 30,
    "stripeFeeNote": "Stripe fees are estimates for standard domestic card payments and can vary based on card type, country, disputes, taxes, and other Stripe adjustments.",
    "currency": "usd",
    "creatorSharePercent": 95,
    "note": "Platform fees apply before Stripe processing fees, taxes, refunds, and disputes.",
    "stripeFeeDisclaimer": "Stripe fees are estimates for standard domestic card payments and can vary based on card type, country, disputes, taxes, and other Stripe adjustments.",
    "defaultPlatformFeePercent": 5,
    "customPlatformFeePercent": null,
    "usesCustomPlatformFee": false
  },
  "stats": {
    "totalSubscribers": 1,
    "monthlyRecurringRevenueCents": 500,
    "grossMonthlyRecurringRevenueCents": 500,
    "monthlyPlatformFeeCents": 25,
    "monthlyCreatorShareCents": 475,
    "monthlyEstimatedStripeFeeCents": 44,
    "monthlyEstimatedCreatorNetCents": 431,
    "bookCount": 1,
    "noteCount": 1,
    "updateCount": 1,
    "exclusivePostCount": 2
  },
  "plans": [
    {
      "id": "66f2b3c4d5e6f7a8b9c0d1e2",
      "tierNumber": 1,
      "name": "Supporter",
      "description": "Access to subscriber-only updates and tier 1 releases.",
      "monthlyPriceCents": 500,
      "currency": "usd",
      "subscriberCount": 1,
      "isActive": true,
      "monetization": {
        "currency": "usd",
        "grossAmountCents": 500,
        "platformFeePercent": 5,
        "creatorSharePercent": 95,
        "platformFeeCents": 25,
        "creatorShareCents": 475,
        "stripeProcessingFeePercent": 2.9,
        "stripeProcessingFeeFixedCents": 30,
        "estimatedStripeFeeCents": 44,
        "estimatedCreatorNetCents": 431,
        "stripeFeeNote": "Stripe fees are estimates for standard domestic card payments and can vary based on card type, country, disputes, taxes, and other Stripe adjustments."
      }
    }
  ],
  "subscribers": [
    {
      "id": "66f3c4d5e6f7a8b9c0d1e2f3",
      "status": "active",
      "tierNumber": 1,
      "cancelAtPeriodEnd": false,
      "currentPeriodEnd": "2026-10-18T10:15:00.000Z",
      "joinedAt": "2026-09-18T10:15:00.000Z",
      "subscriber": {
        "id": "64c3d4e5f6a7b8c9d0e1f2a3",
        "username": "student_ahmad",
        "profilePicture": null
      },
      "plan": {
        "id": "66f2b3c4d5e6f7a8b9c0d1e2",
        "name": "Supporter",
        "monthlyPriceCents": 500,
        "currency": "usd"
      }
    }
  ],
  "books": [
    {
      "id": "64b2c3d4e5f6a7b8c9d0e1f2",
      "title": "Matn Abi Shuja - Annotated",
      "description": "Line-by-line commentary.",
      "visibility": "public",
      "accessModel": "creator_subscription",
      "requiredSubscriptionTier": 1,
      "lastUpdated": "2026-09-10T08:00:00.000Z"
    }
  ],
  "notes": [
    {
      "id": "65d4e5f6a7b8c9d0e1f2a3b4",
      "title": "Chapter of Purification - Study Notes",
      "visibility": "public",
      "accessModel": "public",
      "requiredSubscriptionTier": null,
      "summary": "An overview of the categories of water and their rulings.",
      "lastModified": "2026-09-12T14:30:00.000Z"
    }
  ],
  "updates": [
    {
      "_id": "66f4d5e6f7a8b9c0d1e2f3a4",
      "creator": "64a1b2c3d4e5f6a7b8c9d0e1",
      "title": "September release schedule",
      "content": "This month we begin the chapter of prayer. New lines every Friday.",
      "previewText": "This month we begin the chapter of prayer. New lines every Friday.",
      "visibility": "subscribers",
      "createdAt": "2026-09-01T12:00:00.000Z",
      "updatedAt": "2026-09-01T12:00:00.000Z",
      "__v": 0
    }
  ]
}
PATCH/creators/me/profile

Update the current user's creator profile

Auth required

Partially updates the public creator profile. Only fields present in the body are changed; string fields are trimmed. The handler does not check approved-creator status, so any authenticated user can set these fields. `slug` is normalized (lowercased; characters other than a-z, 0-9, spaces and hyphens removed; spaces become hyphens; repeated and leading/trailing hyphens collapsed) and must be unique across users; the slugs `admin`, `apply`, `me` and `notes` are reserved. Sending an empty `slug` clears it. `coverImage` and the social links get `https://` prepended when no http(s) scheme is present; empty strings clear them. Status, approval and Stripe Connect fields cannot be changed through this endpoint. Returns the full stored `creatorProfile`.

Body parameters

tagline
string
Short tagline.
bio
string
Creator bio.
publicationTitle
string
Title of the creator's publication/page.
slug
string
Custom creator URL slug. Normalized as described above; must contain at least one letter or number if non-empty, must not be reserved, must be unique.
coverImage
string
Cover image URL. `https://` is prepended if no scheme is given.
bannerText
string
Banner text shown on the creator page.
featuredQuote
string
Featured quote shown on the creator page.
socialLinks
object
Object with any of the keys below. Omitted keys keep their current value.
socialLinks.website
string
Website URL. `https://` is prepended if no scheme is given.
socialLinks.x
string
X (Twitter) URL. `https://` is prepended if no scheme is given.
socialLinks.youtube
string
YouTube URL. `https://` is prepended if no scheme is given.
socialLinks.instagram
string
Instagram URL. `https://` is prepended if no scheme is given.

Errors

  • 400Slug contains no letters or numbers after normalization, or the slug is reserved (`admin`, `apply`, `me`, `notes`)
  • 401No token provided
  • 403Invalid or expired token
  • 409Slug is already taken by another user
  • 500Failed to update creator profile
Request
curl -X PATCH "https://app.ummahspot.com/creators/me/profile" \
  -H "Authorization: Bearer $SHARH_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"tagline":"string"}'
Response · 200
{
  "creatorProfile": {
    "status": "approved",
    "tagline": "Classical fiqh texts made approachable",
    "bio": "I have taught Shafi'i fiqh for ten years and publish annotated translations.",
    "publicationTitle": "The Fiqh Notebook",
    "slug": "fiqh-notebook",
    "coverImage": "https://example.com/cover.jpg",
    "bannerText": "New commentary every week",
    "featuredQuote": "Knowledge is a trust.",
    "socialLinks": {
      "website": "https://example.com",
      "x": "",
      "youtube": "https://youtube.com/@fiqhnotebook",
      "instagram": ""
    },
    "approvedAt": "2026-08-01T09:00:00.000Z",
    "approvedBy": "64a0000000000000000000aa",
    "customPlatformFeePercent": null,
    "stripeConnectAccountId": "acct_XXXXXXXXXXXXXXXX",
    "stripeConnectOnboarded": true,
    "stripeChargesEnabled": true,
    "stripePayoutsEnabled": true
  }
}
POST/creators/me/connect/account-session

Create a Stripe Connect account session for payouts onboarding

Auth required

Approved creators only. If the creator has no Stripe Connect account yet, a US Express account (individual, card_payments + transfers capabilities) is created with the user's email and saved to `creatorProfile.stripeConnectAccountId`. Then a Stripe Account Session is created with the account_onboarding, account_management, notification_banner and payouts embedded components enabled. Use the returned `clientSecret` with Stripe Connect embedded components. No request body is read.

Errors

  • 401No token provided
  • 403Invalid or expired token, or the user is not an approved creator
  • 500Failed to initialize Stripe Connect account tools (Stripe or server error)
Request
curl -X POST "https://app.ummahspot.com/creators/me/connect/account-session" \
  -H "Authorization: Bearer $SHARH_TOKEN"
Response · 200
{
  "accountId": "acct_XXXXXXXXXXXXXXXX",
  "clientSecret": "accs_secret__XXXXXXXXXXXXXXXXXXXXXXXX"
}
PUT/creators/me/plans/:tierNumber

Create or update a subscription plan tier

Auth required

Approved creators only. Upserts the creator's plan for the given tier (1, 2 or 3). On first save a Stripe product is created; on later saves the Stripe product name/description are updated. A new monthly recurring USD Stripe price is created whenever the plan is new or `monthlyPriceCents` differs from the stored value. The plan is always saved with `currency: "usd"` and `isActive: true`. Returns the raw plan document, including its Stripe product and price ids.

Path parameters

tierNumber
number
Tier to create or update. Must be 1, 2 or 3.

Body parameters

namerequired
string
Plan name. Must be non-empty after trimming.
descriptionrequired
string
Plan description. Must be non-empty after trimming.
monthlyPriceCentsrequired
number
Monthly price in US cents. Minimum 100 ($1.00).

Errors

  • 400`tierNumber` is not 1, 2 or 3; missing `name`; `monthlyPriceCents` missing or below 100; or missing `description`
  • 401No token provided
  • 403Invalid or expired token, or the user is not an approved creator
  • 500Failed to save creator plan (Stripe or server error)
Request
curl -X PUT "https://app.ummahspot.com/creators/me/plans/:tierNumber" \
  -H "Authorization: Bearer $SHARH_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name":"string","description":"string","monthlyPriceCents":0}'
Response · 200
{
  "plan": {
    "_id": "66f2b3c4d5e6f7a8b9c0d1e2",
    "creator": "64a1b2c3d4e5f6a7b8c9d0e1",
    "tierNumber": 1,
    "name": "Supporter",
    "description": "Access to subscriber-only updates and tier 1 releases.",
    "monthlyPriceCents": 500,
    "currency": "usd",
    "stripeProductId": "prod_XXXXXXXXXXXXXX",
    "stripePriceId": "price_XXXXXXXXXXXXXXXXXXXXXXXX",
    "isActive": true,
    "createdAt": "2026-09-18T10:15:00.000Z",
    "updatedAt": "2026-09-18T10:15:00.000Z",
    "__v": 0
  }
}
PATCH/creators/me/books/:bookId/access

Set subscription gating on one of your books

Auth required

Approved creators only, and the book must be owned by the authenticated user and not deleted. Sets the book's visibility and access model. When `accessModel` is `creator_subscription`, `requiredSubscriptionTier` is parsed as an integer and clamped to 1-3 (defaulting to 1) and visibility is forced to `public`; otherwise the required tier is cleared to null. Any `accessModel` other than `creator_subscription` is treated as `public`, and any `visibility` other than `private` is treated as `public`. Note that omitted fields fall back to their defaults rather than keeping the current values.

Path parameters

bookId
string
Book ObjectId. Must be owned by the current user.

Body parameters

accessModel
string
`public` or `creator_subscription`.Default: 'public'
requiredSubscriptionTier
number
Minimum subscriber tier (1-3) required to read the book. Only used when `accessModel` is `creator_subscription`; defaults to 1 in that case.Default: null
visibility
string
`public` or `private`. Forced to `public` when `accessModel` is `creator_subscription`.Default: 'public'

Errors

  • 401No token provided
  • 403Invalid or expired token, or the user is not an approved creator
  • 404Book not found, deleted, or not owned by the current user
  • 500Failed to update book access
Request
curl -X PATCH "https://app.ummahspot.com/creators/me/books/:bookId/access" \
  -H "Authorization: Bearer $SHARH_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"accessModel":"string"}'
Response · 200
{
  "book": {
    "id": "64b2c3d4e5f6a7b8c9d0e1f2",
    "title": "Matn Abi Shuja - Annotated",
    "description": "Line-by-line commentary.",
    "visibility": "public",
    "accessModel": "creator_subscription",
    "requiredSubscriptionTier": 2,
    "lastUpdated": "2026-09-10T08:00:00.000Z"
  }
}
PATCH/creators/me/notes/:noteId/access

Set subscription gating on one of your notes

Auth required

Approved creators only, and the note must be owned by the authenticated user. Sets the note's visibility, access model and public summary. When `accessModel` is `creator_subscription`, `requiredSubscriptionTier` is parsed as an integer and clamped to 1-3 (defaulting to 1) and visibility is forced to `public`; otherwise the required tier is cleared to null. Any `accessModel` other than `creator_subscription` is treated as `public`, and any `visibility` other than `private` is treated as `public`. The summary is set from `summary`, else the existing summary, else a text preview of the first note section, with whitespace collapsed and truncated to 220 characters plus `...`. Omitted fields fall back to their defaults rather than keeping the current values.

Path parameters

noteId
string
Note ObjectId. Must be owned by the current user.

Body parameters

accessModel
string
`public` or `creator_subscription`.Default: 'public'
requiredSubscriptionTier
number
Minimum subscriber tier (1-3) required to read the note. Only used when `accessModel` is `creator_subscription`; defaults to 1 in that case.Default: null
visibility
string
`public` or `private`. Forced to `public` when `accessModel` is `creator_subscription`.Default: 'public'
summary
string
Teaser text shown to everyone, including non-subscribers. Truncated to 220 characters.Default: ''

Errors

  • 401No token provided
  • 403Invalid or expired token, or the user is not an approved creator
  • 404Note not found or not owned by the current user
  • 500Failed to update note access
Request
curl -X PATCH "https://app.ummahspot.com/creators/me/notes/:noteId/access" \
  -H "Authorization: Bearer $SHARH_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"accessModel":"string"}'
Response · 200
{
  "note": {
    "id": "65d4e5f6a7b8c9d0e1f2a3b4",
    "title": "Chapter of Purification - Study Notes",
    "visibility": "public",
    "accessModel": "creator_subscription",
    "requiredSubscriptionTier": 1,
    "summary": "An overview of the categories of water and their rulings.",
    "lastModified": "2026-09-12T14:30:00.000Z"
  }
}
POST/creators/me/updates

Post a creator update

Auth required

Approved creators only. Creates a text update that appears in the creator's feed. `previewText` is generated from the content (whitespace collapsed, truncated to 220 characters plus `...`). Any `visibility` value other than `public` is stored as `subscribers`.

Body parameters

contentrequired
string
Update body. Must be non-empty after trimming.
title
string
Optional title.Default: ''
visibility
string
`public` or `subscribers`.Default: 'subscribers'

Errors

  • 400Missing or empty `content`
  • 401No token provided
  • 403Invalid or expired token, or the user is not an approved creator
  • 500Failed to create update
Request
curl -X POST "https://app.ummahspot.com/creators/me/updates" \
  -H "Authorization: Bearer $SHARH_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"content":"string"}'
Response · 201
{
  "update": {
    "_id": "66f4d5e6f7a8b9c0d1e2f3a4",
    "creator": "64a1b2c3d4e5f6a7b8c9d0e1",
    "title": "September release schedule",
    "content": "This month we begin the chapter of prayer. New lines every Friday.",
    "previewText": "This month we begin the chapter of prayer. New lines every Friday.",
    "visibility": "subscribers",
    "createdAt": "2026-09-18T10:15:00.000Z",
    "updatedAt": "2026-09-18T10:15:00.000Z",
    "__v": 0
  }
}
DELETE/creators/me/updates/:updateId

Delete one of your creator updates

Auth required

Permanently deletes a creator update. Only updates created by the authenticated user can be deleted.

Path parameters

updateId
string
CreatorUpdate ObjectId.

Errors

  • 401No token provided
  • 403Invalid or expired token
  • 404Update not found or not owned by the current user
  • 500Failed to delete update
Request
curl -X DELETE "https://app.ummahspot.com/creators/me/updates/:updateId" \
  -H "Authorization: Bearer $SHARH_TOKEN"
Response · 200
{
  "success": true
}
POST/creators/:creatorId/checkout

Start a Stripe Checkout session to subscribe to a creator

Auth required

Creates a Stripe Checkout session (subscription mode) for one of the creator's active plans and returns its id and hosted URL. The creator must be approved, must have a Stripe Connect account with charges and payouts enabled, and must not be the caller. The caller must not already have an active or trialing subscription to this creator. The subscription is created with the creator's effective platform fee as `application_fee_percent` and the creator's Connect account as the transfer destination. Success and cancel URLs are built from the request `Origin` header (falling back to https://sharhapp.com) as `/creators/<slug or id>?subscription=success|cancelled`.

Path parameters

creatorId
string
Creator user ObjectId or creator slug.

Body parameters

tierNumberrequired
number
Tier of the plan to subscribe to (1, 2 or 3). Must match an active plan of the creator.

Errors

  • 400Subscribing to your own plans; creator has no Stripe Connect account; creator's charges/payouts are not enabled yet; or you already have an active subscription to this creator
  • 401No token provided
  • 403Invalid or expired token
  • 404Creator not found or not approved, or no active plan with a Stripe price exists for that tier
  • 500Failed to start creator subscription checkout (Stripe or server error)
Request
curl -X POST "https://app.ummahspot.com/creators/:creatorId/checkout" \
  -H "Authorization: Bearer $SHARH_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"tierNumber":0}'
Response · 200
{
  "id": "cs_test_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
  "url": "https://checkout.stripe.com/c/pay/cs_test_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
}
GET/creators/notes/:noteId

Read a creator note

Auth optional

Returns the full content of a published note. Non-public notes return 404 unless the caller is the note owner or an admin. If the note uses the `creator_subscription` access model with a required tier, the caller must be the owner, an admin, or have an active/trialing subscription to the owner at that tier or higher; otherwise the response is 402 with a locked payload: `{ requiresSubscription: true, message, contentType: "note", contentId, creator, requiredSubscriptionTier }` (where `creator` has the same shape as below). An invalid token is treated as anonymous. Section `notes` is the stored editor content string (BlockNote JSON).

Path parameters

noteId
string
Note ObjectId.

Errors

  • 402Note is subscriber-only and the caller lacks a subscription at the required tier; body is the locked payload described above
  • 404Note not found, or not public and the caller is not the owner or an admin
  • 500Failed to load note
Request
curl -X GET "https://app.ummahspot.com/creators/notes/:noteId" \
  -H "Authorization: Bearer $SHARH_TOKEN"
Response · 200
{
  "note": {
    "id": "65d4e5f6a7b8c9d0e1f2a3b4",
    "title": "Chapter of Purification - Study Notes",
    "summary": "An overview of the categories of water and their rulings.",
    "sections": [
      {
        "id": "65d4e5f6a7b8c9d0e1f2a3b5",
        "title": "Categories of water",
        "notes": "[{\"id\":\"b1\",\"type\":\"paragraph\",\"content\":[{\"type\":\"text\",\"text\":\"Water is of four categories...\",\"styles\":{}}]}]"
      }
    ],
    "visibility": "public",
    "accessModel": "creator_subscription",
    "requiredSubscriptionTier": 1,
    "lastModified": "2026-09-12T14:30:00.000Z",
    "creator": {
      "id": "64a1b2c3d4e5f6a7b8c9d0e1",
      "username": "ustadh_yusuf",
      "profilePicture": null,
      "tagline": "Classical fiqh texts made approachable",
      "bio": "I have taught Shafi'i fiqh for ten years and publish annotated translations.",
      "publicationTitle": "The Fiqh Notebook",
      "slug": "fiqh-notebook",
      "coverImage": "https://example.com/cover.jpg",
      "bannerText": "New commentary every week",
      "featuredQuote": "Knowledge is a trust.",
      "socialLinks": {
        "website": "https://example.com",
        "x": "",
        "youtube": "https://youtube.com/@fiqhnotebook",
        "instagram": ""
      },
      "creatorStatus": "approved"
    }
  }
}
GET/creators

List approved creators

Public

Public directory of all approved creators, most recently approved first. Not paginated. Each entry contains the serialized creator profile, counts of public (non-deleted) books and public notes, the creator's active plans with payout breakdowns (honouring any per-creator platform fee override), and summary stats. In this listing every plan's `subscriberCount` is always 0; use `stats.totalSubscribers` (active/trialing subscriptions whose period has not ended) instead. `startingPriceCents` and `highestPriceCents` are null when the creator has no active plans.

Errors

  • 500Failed to load creators
Request
curl -X GET "https://app.ummahspot.com/creators"
Response · 200
{
  "creators": [
    {
      "id": "64a1b2c3d4e5f6a7b8c9d0e1",
      "username": "ustadh_yusuf",
      "profilePicture": "https://example-bucket.s3.amazonaws.com/profile-pictures/64a1b2c3.jpg",
      "tagline": "Classical fiqh texts made approachable",
      "bio": "I have taught Shafi'i fiqh for ten years and publish annotated translations.",
      "publicationTitle": "The Fiqh Notebook",
      "slug": "fiqh-notebook",
      "coverImage": "https://example.com/cover.jpg",
      "bannerText": "New commentary every week",
      "featuredQuote": "Knowledge is a trust.",
      "socialLinks": {
        "website": "https://example.com",
        "x": "",
        "youtube": "https://youtube.com/@fiqhnotebook",
        "instagram": ""
      },
      "creatorStatus": "approved",
      "bookCount": 3,
      "noteCount": 5,
      "plans": [
        {
          "id": "66f2b3c4d5e6f7a8b9c0d1e2",
          "tierNumber": 1,
          "name": "Supporter",
          "description": "Access to subscriber-only updates and tier 1 releases.",
          "monthlyPriceCents": 500,
          "currency": "usd",
          "subscriberCount": 0,
          "isActive": true,
          "monetization": {
            "currency": "usd",
            "grossAmountCents": 500,
            "platformFeePercent": 5,
            "creatorSharePercent": 95,
            "platformFeeCents": 25,
            "creatorShareCents": 475,
            "stripeProcessingFeePercent": 2.9,
            "stripeProcessingFeeFixedCents": 30,
            "estimatedStripeFeeCents": 44,
            "estimatedCreatorNetCents": 431,
            "stripeFeeNote": "Stripe fees are estimates for standard domestic card payments and can vary based on card type, country, disputes, taxes, and other Stripe adjustments."
          }
        }
      ],
      "stats": {
        "totalSubscribers": 12,
        "tierCount": 1,
        "startingPriceCents": 500,
        "highestPriceCents": 500,
        "publicReleaseCount": 8,
        "subscriberOnlyReleaseCount": 2
      }
    }
  ]
}
GET/creators/:creatorId

Get a creator's public page

Auth optional

Returns an approved creator's profile, active plans (with active subscriber counts and payout breakdowns), and a combined feed of their public non-deleted books, public notes and all creator updates, sorted newest first. The creator can be addressed by user ObjectId or by slug. When authenticated, `currentSubscription` is the caller's active/trialing subscription to this creator (highest tier) or null, and `viewerTier` is its tier number (0 when none). Book and note feed items are marked `locked` when they use the `creator_subscription` access model and the viewer's tier is below `requiredSubscriptionTier`; updates with `subscribers` visibility are `locked` when the viewer has no subscription at any tier. Locked items are still listed: books and notes expose only title, description/summary and metadata, and for locked updates `content` is `null` — the subscriber-only text is never sent to non-subscribers — while `previewText` and `description` carry the preview text. For unlocked updates `content` and `description` both hold the full text (as in the example below, where the viewer holds a tier 1 subscription). Nothing is locked for the creator themselves or for admins (`canManage: true`), who additionally receive `manageBooks` and `manageNotes` listing all of the creator's non-deleted books and all notes (including private ones) with their access settings; for other viewers both arrays are empty. An invalid token is treated as anonymous. Updates without a title get the title `Creator Update`.

Path parameters

creatorId
string
Creator user ObjectId or creator slug.

Errors

  • 404Creator not found or not an approved creator
  • 500Failed to load creator page
Request
curl -X GET "https://app.ummahspot.com/creators/:creatorId" \
  -H "Authorization: Bearer $SHARH_TOKEN"
Response · 200
{
  "creator": {
    "id": "64a1b2c3d4e5f6a7b8c9d0e1",
    "username": "ustadh_yusuf",
    "profilePicture": "https://example-bucket.s3.amazonaws.com/profile-pictures/64a1b2c3.jpg",
    "tagline": "Classical fiqh texts made approachable",
    "bio": "I have taught Shafi'i fiqh for ten years and publish annotated translations.",
    "publicationTitle": "The Fiqh Notebook",
    "slug": "fiqh-notebook",
    "coverImage": "https://example.com/cover.jpg",
    "bannerText": "New commentary every week",
    "featuredQuote": "Knowledge is a trust.",
    "socialLinks": {
      "website": "https://example.com",
      "x": "",
      "youtube": "https://youtube.com/@fiqhnotebook",
      "instagram": ""
    },
    "creatorStatus": "approved"
  },
  "plans": [
    {
      "id": "66f2b3c4d5e6f7a8b9c0d1e2",
      "tierNumber": 1,
      "name": "Supporter",
      "description": "Access to subscriber-only updates and tier 1 releases.",
      "monthlyPriceCents": 500,
      "currency": "usd",
      "subscriberCount": 12,
      "isActive": true,
      "monetization": {
        "currency": "usd",
        "grossAmountCents": 500,
        "platformFeePercent": 5,
        "creatorSharePercent": 95,
        "platformFeeCents": 25,
        "creatorShareCents": 475,
        "stripeProcessingFeePercent": 2.9,
        "stripeProcessingFeeFixedCents": 30,
        "estimatedStripeFeeCents": 44,
        "estimatedCreatorNetCents": 431,
        "stripeFeeNote": "Stripe fees are estimates for standard domestic card payments and can vary based on card type, country, disputes, taxes, and other Stripe adjustments."
      }
    }
  ],
  "currentSubscription": {
    "id": "66f3c4d5e6f7a8b9c0d1e2f3",
    "tierNumber": 1,
    "status": "active",
    "currentPeriodEnd": "2026-10-18T10:15:00.000Z",
    "cancelAtPeriodEnd": false
  },
  "viewerTier": 1,
  "canManage": false,
  "manageBooks": [],
  "manageNotes": [],
  "stats": {
    "totalSubscribers": 12,
    "exclusivePostCount": 2,
    "totalFeedItems": 3,
    "bookCount": 1,
    "noteCount": 1,
    "updateCount": 1
  },
  "feed": [
    {
      "id": "65d4e5f6a7b8c9d0e1f2a3b4",
      "type": "note",
      "title": "Chapter of Purification - Study Notes",
      "description": "An overview of the categories of water and their rulings.",
      "accessModel": "public",
      "requiredSubscriptionTier": null,
      "locked": false,
      "href": "/creator-notes/65d4e5f6a7b8c9d0e1f2a3b4",
      "publishedAt": "2026-09-12T14:30:00.000Z"
    },
    {
      "id": "64b2c3d4e5f6a7b8c9d0e1f2",
      "type": "book",
      "title": "Matn Abi Shuja - Annotated",
      "description": "Line-by-line commentary.",
      "accessModel": "creator_subscription",
      "requiredSubscriptionTier": 2,
      "locked": true,
      "href": "/books/64b2c3d4e5f6a7b8c9d0e1f2",
      "publishedAt": "2026-09-10T08:00:00.000Z"
    },
    {
      "id": "66f4d5e6f7a8b9c0d1e2f3a4",
      "type": "update",
      "title": "September release schedule",
      "content": "This month we begin the chapter of prayer. New lines every Friday.",
      "previewText": "This month we begin the chapter of prayer. New lines every Friday.",
      "description": "This month we begin the chapter of prayer. New lines every Friday.",
      "locked": false,
      "visibility": "subscribers",
      "publishedAt": "2026-09-01T12:00:00.000Z"
    }
  ]
}