Reference
Members

Members

Methods of @cobuntu/embed for the signed-in member's account (me), tiers and applications, rules and the member roster. Setup, sessions and errors are on the client overview; each method links to its endpoint in the REST API reference.

me (session)

me.tickets

tickets({ when? })

Route: GET /me/tickets
Returns: Ticket[]

me.membership.get

membership.get()

Route: GET /me/membership
Returns: Membership or null

me.membership.checkout

membership.checkout({ segmentId, billingCycle, successUrl, cancelUrl })

Route: POST /me/membership/checkout
Returns: { checkoutUrl, sessionId }

me.membership.changeTier

membership.changeTier({ segmentId, billingCycle, successUrl, cancelUrl })

Route: POST /me/membership/change-tier
Returns: { status: "CHECKOUT_REQUIRED", checkoutUrl, sessionId } | { status: "CHANGED" | "SCHEDULED", membership }. Switching from a free tier cancels it first.

me.membership.cancel

membership.cancel()

Route: POST /me/membership/cancel
Returns: Membership (cancels at period end)

me.membership.reactivate

membership.reactivate()

Route: POST /me/membership/reactivate
Returns: Membership

me.membership.billingPortal

membership.billingPortal({ returnUrl })

Route: POST /me/membership/billing-portal
Returns: { url }

me.onboarding.get

onboarding.get()

Route: GET /me/onboarding
Returns: Onboarding

me.onboarding.data

onboarding.data({ segmentId, answers })

Route: POST /me/onboarding/data
Returns: Onboarding

me.onboarding.rules

onboarding.rules()

Route: POST /me/onboarding/rules
Returns: Onboarding

me.profile.get

profile.get()

Route: GET /me/profile
Returns: Profile

me.profile.update

profile.update({ name?, bio?, avatarUrl?, phone?, location?, locationVisibility?, languages?, hideFromDirectory?, usertag?, pronouns?, gender?, signature?, socials?, birthday?, emailVisibility?, phoneVisibility? })

Route: PATCH /me/profile
Returns: Profile. A taken usertag is 409 USERTAG_TAKEN with alternatives.

me.profile.events

profile.events()

Route: GET /me/profile/events
Returns: ProfileEvent[]: every event the member hosts, newest first, drafts included, each with catalogStatus (LIVE | PENDING | HIDDEN | REJECTED | DRAFT), catalogRejectionReason when declined with a reason, isDraft and draftStep. Only ever the caller's own rows.

me.profile.usertagAvailable

profile.usertagAvailable(usertag)

Route: GET /me/profile/usertag-available
Returns: { available, alternatives }. The member's own usertag counts as available; alternatives are already checked as free.

me.profile.avatar.upload

profile.avatar.upload(base64Image)

Route: PUT /me/profile/avatar
Returns: The new avatar URL. A png, jpeg or webp data URL up to 5 MB (INVALID_IMAGE, IMAGE_TOO_LARGE).

me.profile.avatar.remove

profile.avatar.remove()

Route: DELETE /me/profile/avatar
Returns: null

me.preferences.get / me.preferences.update

preferences.get() / .update({ locale?, timeFormat?, receivePromotionalContent?, notifications? })

Route: GET / PATCH /me/preferences
Returns: Preferences. notifications holds this community's email preferences and is merged on update.

me.password.change

password.change({ currentPassword, newPassword })

Route: POST /me/password
Returns: { ok, token }. Every session is signed out; store token as the new session.

me.export

export()

Route: GET /me/export
Returns: The account's data export as JSON

me.account.delete

account.delete({ password? })

Route: DELETE /me/account
Returns: { ok, status: "done" | "pending" }. Deletes the whole account, not only the membership.

me.friends.list

friends.list({ limit?, cursor? })

Route: GET /me/friends
Returns: { items: Friend[], nextCursor }

me.friends.remove

friends.remove(usertag)

Route: DELETE /me/friends/:usertag
Returns: undefined (204). FRIENDSHIP_NOT_FOUND

me.friends.requests.list

friends.requests.list(direction?)

Route: GET /me/friends/requests?direction=
Returns: FriendRequest[] ({ id, user, createdAt }), newest first. "incoming" (default) or "outgoing".

me.friends.requests.send

friends.requests.send(usertag)

Route: POST /me/friends/requests
Returns: "pending" | "accepted". Target must be a member here (MEMBER_NOT_FOUND). SELF_REQUEST, ALREADY_EXISTS

me.friends.requests.accept

friends.requests.accept(id)

Route: POST /me/friends/requests/:id/accept
Returns: "accepted". Receiver only; REQUEST_NOT_FOUND

me.friends.requests.decline

friends.requests.decline(id)

Route: POST /me/friends/requests/:id/decline
Returns: undefined (204). Receiver only

me.friends.requests.cancel

friends.requests.cancel(id)

Route: DELETE /me/friends/requests/:id
Returns: undefined (204). Your outgoing request

me.notifications.list

notifications.list({ limit?, cursor?, unread? })

Route: GET /me/notifications
Returns: { items: Notification[], nextCursor }: this community's rows plus friendship rows, newest first

me.notifications.unreadCount

notifications.unreadCount()

Route: GET /me/notifications/unread-count
Returns: number. Poll this.

me.notifications.markRead

notifications.markRead({ ids } | { all: true })

Route: POST /me/notifications/read
Returns: number of rows updated (within this community's scope)

me.notifications.muteThread / me.notifications.unmuteThread

notifications.muteThread(postId) / .unmuteThread(postId)

Route: POST / DELETE /me/notifications/mute-thread
Returns: boolean (muted)

me.referrals.get

referrals.get()

Route: GET /me/referrals
Returns: ReferralSummary: { programEnabled, payoutsConnected, link, links, joins, counts }

me.referrals.earnings

referrals.earnings()

Route: GET /me/referrals/earnings
Returns: ReferralEarnings: { totals, payments }, in cents

me.emails.list

emails.list()

Route: GET /me/emails
Returns: AccountEmail[], primary first

me.emails.add

emails.add(email)

Route: POST /me/emails
Returns: AccountEmail (unverified). INVALID_EMAIL, EMAIL_TAKEN, EMAIL_ALREADY_YOURS

me.emails.resendVerification

emails.resendVerification(id)

Route: POST /me/emails/:id/resend-verification
Returns: { sent: true }. EMAIL_NOT_FOUND, ALREADY_VERIFIED

me.emails.makePrimary

emails.makePrimary(id)

Route: POST /me/emails/:id/make-primary
Returns: AccountEmail. EMAIL_NOT_VERIFIED

me.emails.remove

emails.remove(id)

Route: DELETE /me/emails/:id
Returns: { removed: true }. REMOVE_PRIMARY

me.phone.sendOtp

phone.sendOtp(phoneNumber)

Route: POST /me/phone/send-otp
Returns: { sent: true }. E.164. INVALID_PHONE, RATE_LIMITED, PHONE_UNAVAILABLE

me.phone.verify

phone.verify({ phoneNumber, code })

Route: POST /me/phone/verify
Returns: { phoneNumber, phoneVerified: true }. INVALID_CODE, PHONE_TAKEN, OTP_THROTTLED

me.connectedAccounts.list

connectedAccounts.list()

Route: GET /me/connected-accounts
Returns: { accounts, google: { linked, email, connectedAt } }

me.connectedAccounts.google.link

connectedAccounts.google.link({ returnUrl, codeChallenge, state? })

Route: POST /me/connected-accounts/google/link
Returns: The Google URL (a string). RETURN_URL_NOT_ALLOWED

me.connectedAccounts.google.confirm

connectedAccounts.google.confirm({ code, codeVerifier })

Route: POST /me/connected-accounts/google/confirm
Returns: { linked: true, email }. Same session as link. INVALID_CODE, IDENTITY_TAKEN

me.connectedAccounts.google.unlink

connectedAccounts.google.unlink()

Route: DELETE /me/connected-accounts/google
Returns: { removed: true }. NOT_LINKED, LAST_CREDENTIAL

me.sellerVat.get / me.sellerVat.update

sellerVat.get() / .update({ vatRegistered?, vatCountry?, vatNumber? })

Route: GET / PUT /me/seller-vat
Returns: { vatRegistered, vatCountry, vatNumber }. INVALID_VAT_COUNTRY, VAT_NUMBER_REQUIRED

me.notes.list / me.notes.create / me.notes.delete

notes.list() / .create({ content, category? }) / .delete(id)

Route: GET / POST /me/notes, DELETE /me/notes/:id
Returns: Note[] / Note / undefined. Notes belong to the account and show in every community.

me.directory

directory({ q?, tier?, location?, language?, role?, cursor?, limit? })

Route: GET /me/directory
Returns: { members, facets, nextCursor }

me.member

member(usertag)

Route: GET /me/members/:usertag
Returns: MemberProfile: hostedEvents, plus signature, gender, friendsCount, mutualFriendsCount, friendship, friendRequestId, contact, notes

me.member.events

member.events(usertag)

Route: GET /me/members/:usertag/events
Returns: ProfileEvent[]: the member's live events here that the viewer may see

me.member.friends

member.friends(usertag, { limit?, cursor? })

Route: GET /me/members/:usertag/friends
Returns: { items: Friend[], nextCursor }

me.applications.list

applications.list()

Route: GET /me/applications
Returns: Application[]

me.applications.checkout

applications.checkout(requestId, { successUrl, cancelUrl })

Route: POST /me/applications/:requestId/checkout
Returns: { checkoutUrl, sessionId }

me.segments.apply

segments.apply(segmentId, { answers?, billingCycle?, currency?, source?, referralCode? })

Route: POST /me/segments/:segmentId/apply
Returns: { status: "JOINED" | "PENDING" | "PAYMENT_REQUIRED", ... }

me.reminderPreferences.get / me.reminderPreferences.update

reminderPreferences.get() / .update({ emailReminders })

Route: GET / PATCH /me/reminder-preferences
Returns: { emailReminders }

me.verifyEmailResend

verifyEmailResend()

Route: POST /me/verify-email/resend
Returns: { sent: true }

me.sales.refundEligibility

sales.refundEligibility(saleId)

Route: GET /me/sales/:saleId/refund-eligibility
Returns: { eligible, reason, windowEndsAt }

me.purchases

purchases({ limit?, offset? })

Route: GET /me/purchases
Returns: { purchases: Purchase[], total, hasMore }, newest first (limit 1-50)

me.purchaseDownload

purchaseDownload(saleId, attachmentId)

Route: GET /me/purchases/:saleId/attachments/:attachmentId/download
Returns: { url, expiresAt, maxDownloads, remainingDownloads }. The URL is signed for about 5 minutes; each call counts one download.

me.invoice

invoice(saleId)

Route: GET /me/sales/:saleId/invoice
Returns: The hosted invoice page URL (a string). INVOICE_NOT_AVAILABLE until issued.

me.receipt

receipt(saleId)

Route: GET /me/sales/:saleId/receipt
Returns: The receipt PDF as a Blob

me.events

events({ when?, role? })

Route: GET /me/events
Returns: { attending, attended, hosting, hosted }, each MemberEvent[]. A group excluded by when (upcoming | past) or role (attending | hosting) is [].

me.ledger

ledger({ type?, from?, to?, limit?, offset? })

Route: GET /me/ledger
Returns: { entries: LedgerEntry[], total, hasMore, summary }, newest first. type is purchase | refund | sale; limit 1-100, default 20.

me.library

library()

Route: GET /me/library
Returns: { items: LibraryItem[], total }: owned items with their downloads

segments (tiers) and apply

segments.public

segments.public()

Route: GET /segments/public
Returns: PublicSegment[] (prices per cadence, in cents)

segments.form

segments.form(segmentId, { invitationToken? })

Route: GET /segments/:segmentId/form
Returns: SegmentForm. A hidden tier needs its invitationToken.

segments.checkEmail

segments.checkEmail(segmentId, email)

Route: GET /segments/:segmentId/check-email
Returns: { status: "pending_application" | "existing_member" | "has_account" | "new" }

segments.submit

segments.submit(segmentId, { answers, invitationToken?, billingCycle?, currency? })

Route: POST /segments/:segmentId/submit
Returns: { success, requestId, paymentRequired?, autoApproved?, awaitingEmailConfirmation?, ... }. See Security model.

members.list

members.list({ usertags?, limit?, offset? })

Route: GET /members
Returns: { members: Member[], pagination }, newest accepted first. Follows the Members page setting: 403 MEMBERS_ONLY, 404 PAGE_DISABLED; the full roster needs a secret key with MEMBERS_ADMIN.

members.get

members.get(userIdOrUsertag)

Route: GET /members/:userId
Returns: Member. Same gate; a member hidden from the directory is 404 without MEMBERS_ADMIN.

members.membership

members.membership(userId)

Route: GET /members/:userId/membership
Returns: MemberMembership. permissions / segments only for a secret key with APP_ONBOARDING or MEMBERS_ADMIN.

apply.checkout

apply.checkout({ requestId, successUrl?, cancelUrl? })

Route: POST /apply/checkout
Returns: { checkoutUrl, sessionId }

rules

rules

rules()

Route: GET /rules
Returns: CommunityRule[]

v1 has no single-article route, so articles.get pages through the list 100 at a time. Cache the answer if you call it on every request.