Achievements
The public badge catalogue, single badges, the "just earned" feed, and individual earned cards with their share pictures and verify QR codes.
Get the badge catalogue
Every badge on the platform with its copy, tier ladder, holder counts and rarity, plus header totals, series and the grid's slots, in the reader's language (?lang=, then Accept-Language, then the i18next cookie). The payload is the same for every reader; a token is accepted and ignored. Cached per language.
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
Query Parameters
Reader language; falls back to Accept-Language, then the i18next cookie, then English.
"en""ru""uk""es"Responses
Catalogue (bare object)
Get an achievement art sheet image
The image of one badge art sheet, served immutably (one year) under its version token ?v=. A request without the current token is redirected (302, uncached) to the current versioned URL. Public.
Parameters
Path Parameters
"uuid"Query Parameters
Anything else is the full sheet.
"full""small""cutout""cutout_small""full"Version token. Cut-out sizes append -c.
Responses
The image (its stored content type)
Get an achievement library image
One image from the badge art library, served immutably under its version token ?v=; a request without the current token is redirected (302) to it. Public.
Parameters
Path Parameters
Query Parameters
"full""small""full"Responses
The image (its stored content type)
Get the achievement vocabulary
The labels and colours every badge card is drawn with (tiers, tracks, rarity frames and so on), in the reader's language. Public.
Parameters
Query Parameters
Reader language; falls back to Accept-Language, then the i18next cookie, then English.
"en""ru""uk""es"Responses
Vocabulary
Get the "just earned" feed
The most recent cards issued or upgraded, platform-wide or for one badge (species). The size, maximum age and suggested refresh interval come from platform settings. An unknown, hidden or private badge answers an empty list. Public; sent with Cache-Control: no-store.
Parameters
Query Parameters
A badge slug. Repeating the parameter answers an empty list.
Reader language; falls back to Accept-Language, then the i18next cookie, then English.
"en""ru""uk""es"Responses
Feed
Get one badge
One badge with its copy, ladder and rarity. Authentication is optional: a signed-in reader also gets their own standing (earned, tier, progress). With holder_type and holder_id, the badge is answered for that holder instead (a profile's or organization's badge); both must be given together.
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
"user""organization""uuid"Reader language; falls back to Accept-Language, then the i18next cookie, then English.
"en""ru""uk""es"Responses
The badge
Get a badge share picture
A PNG of the badge for sharing: og 1200×630, post 1080×1080, story and reel 1080×1920. A trailing .png on asset is accepted. ?tier= draws it at that tier when the tier exists. Drafts and private badges answer 404. Public; cached for 5 minutes.
Parameters
Path Parameters
"og""post""story""reel""og.png""post.png""story.png""reel.png"Query Parameters
Reader language; falls back to Accept-Language, then the i18next cookie, then English.
"en""ru""uk""es"Responses
PNG image
Get an earned card
One earned card by its short code, as the card's public page shows it: the badge, holder, tier, dates, serial, evidence, ladder, rarity, the verify URL and share links. Authentication is optional; the holder's own session adds an owner block. Sent private, no-store.
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
The card's short code.
Query Parameters
Reader language; falls back to Accept-Language, then the i18next cookie, then English.
"en""ru""uk""es"Responses
The card
Get an earned card's share picture
A PNG of one earned card: og 1200×630, post 1080×1080, story 1080×1920 (a trailing .png is accepted). Served only when the card is readable by a stranger. When the card's own picture is not rendered yet, the badge's generic picture is served with X-Card-Render: pending and no-store. Supports If-None-Match (304). Public; a per-IP limit (120 per minute by default) applies in addition to the public browsing limit.
Parameters
Path Parameters
The card's short code.
"og""post""story""og.png""post.png""story.png"Query Parameters
Responses
PNG image. Content-Language names the language it was drawn in.
Get an earned card's verify QR code
An SVG QR code pointing at the card's verify URL. Only for cards readable by a stranger. Public; same per-IP limit as the share pictures. Cached for 60 seconds.
Parameters
Path Parameters
The card's short code.
Responses
SVG image
Get a profile's achievements
The achievements section of a profile: the badges the person has earned that visitors may see, each with its card, plus a public holder block, a summary counted over the returned rows, the profile's pinned card and the label vocabulary. id is a UUID or a profile slug.
The answer is the same for everyone, the owner included, except that the owner's own rows carry their counts (stats). A private or inactive profile read by anyone but its owner answers { "data": [], "withheld": true, "vocabulary": … }.
Authentication is optional. 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
Locale for titles and labels; unsupported locales fall back to English.
Responses
The collection, or a withheld answer
Get my achievements
The owner view: every achievement the caller holds — themselves and through organizations they administer — including those set to "only me", with private stats and progress; next_up, the closest badges not yet earned; the caller's pin; and how many new cards are waiting to be revealed.
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
Query Parameters
Responses
The owner collection
Pin an achievement card
Pins one of the caller's own live cards (theirs, or an organization's they administer) to that holder's profile. A malformed, unknown, void or someone else's card all get the same 404 body, so the answer never says whether a code exists. Responses are private, no-store.
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
Pinned
Unpin an achievement card
Clears the caller's pin, or with organization that organization's pin when the caller administers it. Idempotent. The profile then shows the automatic choice.
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
Query Parameters
"uuid"Responses
Unpinned
Get my reveal pack
Cards waiting to be "opened": with receipt, the ones a particular donation earned (the thank-you page — status: pending while the award is still being computed); with all=true, every unrevealed card. Pass exactly one. Someone else's receipt answers like a donation that earned nothing (status: none). Responses are private, no-store.
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
Query Parameters
A Stripe PaymentIntent id.
"^pi_[A-Za-z0-9_]{1,255}$""true"Responses
The pack
Mark reveal events as opened
Marks the caller's own reveal events as revealed. Ids that are not the caller's are ignored silently; the answer is 204 either way.
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
Acknowledged
Set an achievement's visibility
The holder's "Visible to: Everyone / Only me" control for one badge. default follows the badge's own visibility. When the caller wears the badge both personally and through an organization (or through two organizations), holder must say which; otherwise 409 with the list of holders.
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
The achievement's slug.
Request Body
Responses
The updated award