Get user profile
Public profile by UUID or profile_slug. Authentication is optional: the caller's own profile may include their email, and a profile marked private is redacted for every other viewer.
WHAT SURVIVES THE REDACTION (#1696): id, name, avatar, profile_slug, created_at and the four counters — campaign_count, total_funds_raised, follower_count and following_count — with their REAL values. The leaderboard has always published a private person's rank and impact, so a profile reporting zeroes beside a board reporting real figures would be two surfaces disagreeing about one person rather than privacy.
Dropped: bio, location, website, social_links, email, phone, private_contact_email, display_name, account_status, kyc_verified_at and account_kind. The last three are more than a name — a Team chip and a verification tick say something about the person, which is exactly what a private profile withholds.
Authorizations
In the browser, authentication rides on the httpOnly session cookies set by /cognito/signin or the Google / Apple sign-in at /cognito/oauth/{provider}. For scripts and for Swagger UI testing, paste an API key (fh_live_…, created with POST /api-keys); a Cognito JWT is accepted too. Sign-in does not return a token in its body.
Parameters
Path Parameters
User UUID or profile_slug.
Responses
User profile — a bare object, not wrapped in data. The fields marked own profile only are present only when the caller is the profile's owner.
Update user profile
Update your own profile. The fields below are the whole writable set;
anything else in the body is ignored rather than rejected.
location has been accepted since #1654 and was missing from this
schema; profile_visibility is new in #1696.
Authorizations
In the browser, authentication rides on the httpOnly session cookies set by /cognito/signin or the Google / Apple sign-in at /cognito/oauth/{provider}. For scripts and for Swagger UI testing, paste an API key (fh_live_…, created with POST /api-keys); a Cognito JWT is accepted too. Sign-in does not return a token in its body.
Parameters
Path Parameters
Request Body
Responses
Profile updated
Get a user's organization memberships
Public org memberships for a user (UUID or profile_slug). Memberships marked not publicly visible, memberships of deleted organizations, and every membership of a private profile — even to its owner — are left out. 404 only when the user does not exist.
Authorizations
In the browser, authentication rides on the httpOnly session cookies set by /cognito/signin or the Google / Apple sign-in at /cognito/oauth/{provider}. For scripts and for Swagger UI testing, paste an API key (fh_live_…, created with POST /api-keys); a Cognito JWT is accepted too. Sign-in does not return a token in its body.
Parameters
Path Parameters
Responses
User organizations
Get a user's public activity feed
The public activity feed on a profile (#1693): six kinds of public act, ordered newest first. Accepts a UUID or a profile_slug; auth-optional.
campaign_launched (the campaign passed approval), achievement_earned (a badge, read through the same public projection the profile badge strip uses), commented, donated, update_posted and endorsed (declared, or their referral link for that campaign recorded a visit — the definition the Endorsed-by dialog and the profile chip already use).
Each row inherits the visibility of the thing it reports: a refunded or charged-back gift, a hidden or retracted comment, a withdrawn update, a soft-deleted campaign and a revoked award are all simply absent. Anonymous gifts never appear, for anyone, including the profile's owner. A campaign that is unlisted, private, paused, draft or deleted is never named. A profile with show_donations_on_profile off keeps every row type except donated.
All money is INTEGER CENTS, never dollars. amount_cents on a donated row is what the giver paid — the donation plus the platform tip — which is the same figure the profile's Impact stat sums, so the two cannot disagree.
Paging is a KEYSET cursor, not an offset: pass the nextCursor from the previous page back as cursor. A cursor this endpoint did not issue is a 400. nextCursor is null on the last page.
Parameters
Path Parameters
A user UUID or a profile_slug.
Query Parameters
Filter chip. giving is donated; fundraising is campaign_launched and update_posted; community is commented, achievement_earned and endorsed. An unrecognised value falls back to all. The summary block is NOT filtered — it is the strip above the chips and always counts every type.
"all""giving""fundraising""community""all"15020The opaque nextCursor from the previous page. Omit for page 1.
Responses
A page of the feed. A private profile answers 200 with an empty items array to everybody but its owner, rather than 404 — the page renders and the section is simply empty.
Get a user's public donation activity
"Causes I support" on a public profile — the aggregate plus one entry per supported campaign. Accepts a UUID or a profile_slug; 404 only when the user does not exist.
Anonymous gifts are excluded, always. A profile that is private, or that has show_donations_on_profile off, answers zeroes. Only settled (paid) gifts count, and only to a campaign a reader could actually open — a deleted, draft, private, paused or unlisted campaign is neither listed nor counted (#1694).
Each entry in recent_supported_causes is a full campaign card, the same read model /fundraisers serves the /causes grid from, so the section renders the card the rest of the product uses. total_cents figures are INTEGER CENTS.
total_donated_cents is the PUBLIC figure and excludes anonymous gifts. It is the GIVER-FACING value of those gifts — the donation plus the platform tip, which is what the card was charged — so it agrees with the profile activity feed's per-gift figures and with the leaderboard's given figure. /donor/me/summary counts every gift the owner made and is a different number by design; do not compare them.
currency is the ISO 4217 code total_donated_cents is denominated in, taken from the donor's most recent gift that named one. Read it: minor units are not always hundredths, so formatting the total without it is a 100x error for a zero-decimal currency, not just the wrong symbol.
Authorizations
In the browser, authentication rides on the httpOnly session cookies set by /cognito/signin or the Google / Apple sign-in at /cognito/oauth/{provider}. For scripts and for Swagger UI testing, paste an API key (fh_live_…, created with POST /api-keys); a Cognito JWT is accepted too. Sign-in does not return a token in its body.
Parameters
Path Parameters
Query Parameters
Causes per page. The profile rail asks for 6; the dedicated page asks for more.
148600Responses
User donation activity
Get a user's Impact and leaderboard rank
The figures behind the Impact stat on a public profile, read from the same all-time field /leaderboard is served from, so the two surfaces always agree. Accepts a UUID or a profile_slug. All money is integer cents. A user who has not moved money answers zeroes and a null rank rather than 404 — their referral impressions are still reported. A private profile answers its headline impact figure only, with the rest of the breakdown zeroed and rank null, to everybody but its owner. If the leaderboard field cannot be read the endpoint answers 200 with zeroes rather than failing the profile.
Authorizations
In the browser, authentication rides on the httpOnly session cookies set by /cognito/signin or the Google / Apple sign-in at /cognito/oauth/{provider}. For scripts and for Swagger UI testing, paste an API key (fh_live_…, created with POST /api-keys); a Cognito JWT is accepted too. Sign-in does not return a token in its body.
Parameters
Path Parameters
Responses
The user's Impact breakdown
Get a user's permissions
Role assignments and effective permissions for the user named in the path. Requires a bearer session. Callers may read their own; reading another user's requires the view_all_users permission, and any other caller gets 403. Answers can be several minutes old; for the caller's own, current permissions use GET /me/capabilities.
Authorizations
In the browser, authentication rides on the httpOnly session cookies set by /cognito/signin or the Google / Apple sign-in at /cognito/oauth/{provider}. For scripts and for Swagger UI testing, paste an API key (fh_live_…, created with POST /api-keys); a Cognito JWT is accepted too. Sign-in does not return a token in its body.
Parameters
Path Parameters
"uuid"Responses
User permissions — a bare object.
Get user preferences
Returns the caller's own preferences. Callers may only access their own — any other path id answers 403.
Accounts with no stored row get a default object rather than a 404, so the returned key set differs slightly between the two cases. suppressed_scopes is always present: it lists the notification scopes this account's email address has been unsubscribed from via an emailed link. Those suppressions are keyed by address, not by account, so they stop mail even while the matching toggle reads true — which is exactly why they are reported separately rather than folded into the toggles.
Authorizations
In the browser, authentication rides on the httpOnly session cookies set by /cognito/signin or the Google / Apple sign-in at /cognito/oauth/{provider}. For scripts and for Swagger UI testing, paste an API key (fh_live_…, created with POST /api-keys); a Cognito JWT is accepted too. Sign-in does not return a token in its body.
Parameters
Path Parameters
Responses
User preferences
Update user preferences
Upserts the caller's own preferences and returns the stored row. Callers may only update their own — any other path id answers 403. suppressed_scopes is read-only and is not accepted here; an address unsubscribed by an emailed link can only be resubscribed through /unsubscribe/resubscribe.
Authorizations
In the browser, authentication rides on the httpOnly session cookies set by /cognito/signin or the Google / Apple sign-in at /cognito/oauth/{provider}. For scripts and for Swagger UI testing, paste an API key (fh_live_…, created with POST /api-keys); a Cognito JWT is accepted too. Sign-in does not return a token in its body.
Parameters
Path Parameters
Request Body
Responses
Updated preferences — the stored row.
Upload user avatar
Upload the caller's own avatar from a base64-encoded image — JPEG, PNG or WebP, at most 5 MB decoded. Callers may only update their own.
Authorizations
In the browser, authentication rides on the httpOnly session cookies set by /cognito/signin or the Google / Apple sign-in at /cognito/oauth/{provider}. For scripts and for Swagger UI testing, paste an API key (fh_live_…, created with POST /api-keys); a Cognito JWT is accepted too. Sign-in does not return a token in its body.
Parameters
Path Parameters
Request Body
Responses
Avatar uploaded
Delete user avatar
Delete the caller's own avatar. Callers may only delete their own.
Authorizations
In the browser, authentication rides on the httpOnly session cookies set by /cognito/signin or the Google / Apple sign-in at /cognito/oauth/{provider}. For scripts and for Swagger UI testing, paste an API key (fh_live_…, created with POST /api-keys); a Cognito JWT is accepted too. Sign-in does not return a token in its body.
Parameters
Path Parameters
Responses
Avatar deleted
Self-deactivate account
Deactivates the caller's own account and clears auth cookies. Callers may only deactivate their own.
Authorizations
In the browser, authentication rides on the httpOnly session cookies set by /cognito/signin or the Google / Apple sign-in at /cognito/oauth/{provider}. For scripts and for Swagger UI testing, paste an API key (fh_live_…, created with POST /api-keys); a Cognito JWT is accepted too. Sign-in does not return a token in its body.
Parameters
Path Parameters
Responses
Account deactivated
Get the pending account deletion
The caller's pending account deletion. awaiting_payout is true once the 30 days have passed and deletion is waiting for money owed to the caller to be paid out.
Authorizations
In the browser, authentication rides on the httpOnly session cookies set by /cognito/signin or the Google / Apple sign-in at /cognito/oauth/{provider}. For scripts and for Swagger UI testing, paste an API key (fh_live_…, created with POST /api-keys); a Cognito JWT is accepted too. Sign-in does not return a token in its body.
Responses
A deletion is pending.
Request account deletion
Schedules deletion of the caller's account 30 days from now. In the same step every personal campaign of theirs that is active, paused or pending is closed (status ended), so it stops taking donations, and every session is signed out: the cookies of this one are cleared, every refresh token is revoked and every API key is revoked. An access token already issued keeps working until it expires (at most an hour).
The person can sign in again during the 30 days, which is how they reach Cancel; GET /cognito/me and the sign-in response then carry deletion_scheduled_for. They cannot publish or reopen a campaign meanwhile (publish blocker account_deletion_pending).
After the 30 days the account is deleted once nothing is owed to the person: money not yet paid out is paid out to their verified payout account first, and deletion waits for it. Donation and payout records are kept, anonymised; everything else is deleted, including the sign-in. Campaigns they created for an organization are the organization's: they keep running, and when the deletion completes they are handed to an owner of that organization, unchanged.
Idempotent: while a request is pending, calling again returns 200 with the same schedule and changes nothing. Requires a signed-in session; refused for an API key and while FundlyHub support is viewing the account.
Authorizations
In the browser, authentication rides on the httpOnly session cookies set by /cognito/signin or the Google / Apple sign-in at /cognito/oauth/{provider}. For scripts and for Swagger UI testing, paste an API key (fh_live_…, created with POST /api-keys); a Cognito JWT is accepted too. Sign-in does not return a token in its body.
Responses
A deletion was already pending; its schedule, unchanged.
Cancel account deletion
Cancels the caller's pending account deletion. Allowed until the deletion has completed. Campaigns the request closed go back to the status they had, if they are still closed and not deleted; any other campaign is left as it is. Requires a signed-in session; refused for an API key and while FundlyHub support is viewing the account.
Authorizations
In the browser, authentication rides on the httpOnly session cookies set by /cognito/signin or the Google / Apple sign-in at /cognito/oauth/{provider}. For scripts and for Swagger UI testing, paste an API key (fh_live_…, created with POST /api-keys); a Cognito JWT is accepted too. Sign-in does not return a token in its body.
Responses
Cancelled.
Set private contact email
Sets the caller's private contact email (visible only to the FundlyHub team). Validates format, blocks disposable domains, and triggers a verification email when the address changes — unless it is the caller's own verified sign-in address, which counts as verified at once. Shares the verification-resend limit: 5 requests per minute per user.
Authorizations
In the browser, authentication rides on the httpOnly session cookies set by /cognito/signin or the Google / Apple sign-in at /cognito/oauth/{provider}. For scripts and for Swagger UI testing, paste an API key (fh_live_…, created with POST /api-keys); a Cognito JWT is accepted too. Sign-in does not return a token in its body.
Request Body
Responses
Private contact email saved
Set phone number
Sets the caller's phone number (stored only; no SMS verification).
Authorizations
In the browser, authentication rides on the httpOnly session cookies set by /cognito/signin or the Google / Apple sign-in at /cognito/oauth/{provider}. For scripts and for Swagger UI testing, paste an API key (fh_live_…, created with POST /api-keys); a Cognito JWT is accepted too. Sign-in does not return a token in its body.
Request Body
Responses
Phone number saved
Get publish-readiness checklist
Returns the publish-gate checklist for the caller (hard blockers + soft suggestions). When the checklist is unavailable the answer is ready: true, checklist: null and migration_pending: true.
Authorizations
In the browser, authentication rides on the httpOnly session cookies set by /cognito/signin or the Google / Apple sign-in at /cognito/oauth/{provider}. For scripts and for Swagger UI testing, paste an API key (fh_live_…, created with POST /api-keys); a Cognito JWT is accepted too. Sign-in does not return a token in its body.
Responses
Publish-readiness status
Check profile slug availability
Get a profile's trust badges
The trust badges (e.g. identity verified, brand ambassador) on a profile, newest first. id is a UUID or a profile slug.
A private profile answers { "badges": [] } to everyone but its owner — the same answer as a profile with no badges, so the response does not confirm that the profile is private.
Authentication is optional; it only matters for the owner.
Authorizations
In the browser, authentication rides on the httpOnly session cookies set by /cognito/signin or the Google / Apple sign-in at /cognito/oauth/{provider}. For scripts and for Swagger UI testing, paste an API key (fh_live_…, created with POST /api-keys); a Cognito JWT is accepted too. Sign-in does not return a token in its body.
Parameters
Path Parameters
Profile UUID or profile slug.
Responses
The badges (bare object, not the data envelope)
List a profile's campaigns
The campaigns shown on a profile: those the person runs, and those they have endorsed (is_endorsed: true), newest activity first. id is a UUID or a profile slug.
A visitor sees public campaigns in active or ended status. The profile's owner, identified by the session (there is no query flag for it), additionally sees their own draft, pending and paused campaigns and their unlisted and private ones. A private profile returns { "data": [] } to everyone but its owner.
Titles and summaries are returned in the reader's language when a translation exists (?lang=, then the language cookie, then Accept-Language).
Rate limited at 300 requests/minute per IP.
Authorizations
In the browser, authentication rides on the httpOnly session cookies set by /cognito/signin or the Google / Apple sign-in at /cognito/oauth/{provider}. For scripts and for Swagger UI testing, paste an API key (fh_live_…, created with POST /api-keys); a Cognito JWT is accepted too. Sign-in does not return a token in its body.
Parameters
Path Parameters
Profile UUID or profile slug.
Query Parameters
110060"en""ru""uk""es"Responses
The profile's campaign cards
Get a profile's share image
The 1200×630 PNG a shared profile link unfurls into: name, avatar, account kind, location, join date and campaign count. Intended for social crawlers. id is a UUID or a profile slug. The name is the profile's display_name: the name, else @handle, else FundlyHub member, never an email address.
A private profile, like a missing one, is a 404. Cached for five minutes, server-side and via Cache-Control.
No authentication. Rate limited at 300 requests/minute per IP.
Parameters
Path Parameters
Profile UUID or profile slug.
Responses
The image
Resend the private-contact verification email
Sends a new verification link to the caller's private contact email (set with PUT /users/me/private-contact). Links last 24 hours; a verified private contact email is required before publishing a campaign. If the address is already verified, nothing is sent and the response says so.
Rate limited at 5 requests/minute per user, a bucket shared with PUT /users/me/private-contact.
Authorizations
In the browser, authentication rides on the httpOnly session cookies set by /cognito/signin or the Google / Apple sign-in at /cognito/oauth/{provider}. For scripts and for Swagger UI testing, paste an API key (fh_live_…, created with POST /api-keys); a Cognito JWT is accepted too. Sign-in does not return a token in its body.
Responses
Sent, or already verified
List top creators
Public profiles ranked by money raised, then followers. Cached server- side; cached says whether this answer came from the cache.
fundsRaised is in DOLLARS (a decimal), unlike the rest of the API, which uses integer cents.
No authentication.
Parameters
Query Parameters
110020Responses
The creators (bare object with data, not paginated)