Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .cursor/rules/localization-workflow.mdc
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ alwaysApply: true
- `scripts/localize-mdx-paths.mjs` rewrites: `<locale>/components/*.jsx` for the active locale; `from ".../snippets/..."`; and JSX `src=".../assets/..."` so `../` depth matches the file’s path. Run after Lingo in `translate:generate` and translate-on-main; CI checks via `translate:localize-mdx-paths:check`.
- Shared MDX snippets live under repo-root `snippets/` (not per-locale). Import with relative paths from each page; do not add shared MDX snippets to Lingo `i18n.json` buckets unless you intend to translate them.
- Locale-aware React components that can contain text live under `components/*.jsx` for default language and `<locale>/components/*.jsx` for targets, and are manually maintained per locale (do not add them to Lingo `i18n.json` buckets; do not keep these in shared `snippets/`).
- Keep OpenAPI specs under repo-root `openapi/` (not under locale folders). Endpoint and webhook MDX must use Mintlify’s form `openapi: openapi/<spec>.yml <method> <path>` or `openapi: openapi/<spec>.yml webhook <eventKey>`. Do not translate the `openapi:` line.
- Endpoint and webhook MDX must use hosted OpenAPI defaults from `docs.json` navigation (`openapi` set to `https://api.trophy.so/v1/openapi` for Application API + webhooks, and `https://admin.trophy.so/v1/openapi` for Admin API). In pages, use Mintlify operation form `openapi: "GET /path"` or webhook form `openapi: "webhook <eventKey>"`. Do not translate or otherwise alter the `openapi:` line.
- English **nav titles** for those pages come from OpenAPI **`summary`** via `scripts/sync-openapi-titles.mjs` (`npm run translate:sync-openapi-titles`). It runs at the start of `translate:generate` and on the translate-on-main workflow. Lingo translates the `title` field for target locales; the script only fills a missing target `title` with English (bootstrap)—it does not overwrite existing translations.
- Mintlify custom heading IDs use markdown `## Title {#slug}` (see Mintlify docs). Slugs are aligned from English source root files via `scripts/sync-heading-anchors.mjs`. Never translate or alter `{#…}`; sync runs after Lingo in PIT/CI. Do not merge heading-count drift between source root and target locales without fixing structure first.
- For Mintlify `<Accordion>` components that may be deep-linked, always set explicit `id` values (do not rely on title-derived hashes) and keep those `id`s identical across locales.
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ Notes:
- **Shared MDX snippets (`snippets/*.mdx`)**: Reusable MDX blocks stay in repo-root `snippets/` (not per-locale). Import them with relative paths from each page (for example `../../snippets/foo.mdx` from `locale/<section>/<page>.mdx`, or more `../` segments for deeper pages). They are excluded from Lingo buckets in `i18n.json` so they stay English and identical everywhere.
- **Localized React components (`components/*.jsx` for default language, `<locale>/components/*.jsx` for targets)**: UI components that can contain locale text are stored per locale (for example `components/rate-limit-badge.jsx`, `es/components/rate-limit-badge.jsx`) and manually maintained per locale (not translated by PIT/CI automation).
- **Media paths**: Default-language pages live at repo root paths like `<section>/<page>.mdx` and target locales live under `<locale>/<section>/<page>.mdx`; shared files sit in repo-root `assets/`. Prefer relative `src="../assets/..."` (or more `../`) from English source; `scripts/localize-mdx-paths.mjs` rewrites `assets/` `src` depth for each target locale file.
- **`openapi/`**: Split OpenAPI 3.1 specs at the **repository root** (for example `openapi/application.yml`, `openapi/admin.yml`). API and webhook pages reference a spec explicitly in frontmatter, for example `openapi: openapi/application.yml get /users/{id}` or `openapi: openapi/application.yml webhook points.changed`. Do not duplicate the YAML under locale folders; Lingo must not alter `openapi:` lines.
- **Hosted OpenAPI specs**: Define hosted OpenAPI sources in `docs.json` navigation (`openapi` on Application API, Admin API, and Webhooks tabs/groups), then reference operations in page frontmatter as `openapi: "GET /users/{id}"` (or `openapi: "webhook points.changed"`). This follows Mintlify’s recommended default-spec inheritance model for hosted specs. Keep `openapi:` lines unchanged across locales; Lingo must not alter them.
- **`scripts/sync-openapi-titles.mjs`**: Copies each operation/webhook **`summary`** from the referenced spec into the English page’s **`title:`** frontmatter (Mintlify’s default when `title` is omitted). Target locales get an English `title` only if missing (bootstrap); run **`npm run translate:generate`** so Lingo translates those titles. Runs automatically at the start of `translate:generate` and in translate-on-main before Lingo.
- `scripts/sync-heading-anchors.mjs`: Writes Mintlify [custom heading IDs](https://www.mintlify.com/docs/create/text#custom-heading-ids) as **`## Title {#slug}`** markdown. Slugs match Mintlify’s auto rules from the **English** title so hashes like `#pro-plan` stay stable across locales. Run `npm run translate:sync-anchors` after bulk heading edits; translation pipelines run it automatically (see **Heading anchors and Lingo** below). The script can also migrate one-line **`<h2 id="slug">…</h2>`** left from older tooling back to `{#slug}` syntax.
- `scripts/validate-glossary-csv.mjs`: Validates glossary schema and duplicate canonical keys. Prefer `npm run lingo:validate-glossary`.
Expand All @@ -92,7 +92,7 @@ Use `npm run <script> -- <args>` when a script needs CLI flags (the `--` forward
| `translate:localize-mdx-paths:check` | CI-style check: fail if any of the above is wrong for its locale/path. |
| `translate:sync-anchors` | Apply English-derived `{#slug}` on default-language root MDX and target locales (see `i18n.json` `locale.targets`). |
| `translate:sync-anchors:check` | Fail if any MDX needs re-sync (CI). |
| `translate:sync-openapi-titles` | Set default-language API & webhook `title:` from `openapi/*.yml` summaries; bootstrap missing target `title` from English. |
| `translate:sync-openapi-titles` | Set default-language API & webhook `title:` from referenced hosted OpenAPI summaries; bootstrap missing target `title` from English. |
| `translate:sync-openapi-titles:check` | CI: fail if any OpenAPI-backed page title differs from the spec. |
| `lingo:validate-glossary` | Validate `lingo/glossary.csv`. |
| `translate:validate` | MDX parity and frontmatter checks (source root -> target locales, e.g. `es`). No `.env` required. |
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: Create application API keys for users
openapi: openapi/admin.yml post /application-api-keys
openapi: "POST /application-api-keys"
---

import { RateLimitBadge } from "../../../components/rate-limit-badge.jsx";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: Delete application API keys
openapi: openapi/admin.yml delete /application-api-keys
openapi: "DELETE /application-api-keys"
---

import { RateLimitBadge } from "../../../components/rate-limit-badge.jsx";
Expand Down
2 changes: 1 addition & 1 deletion admin-api/endpoints/attributes/create-attributes.mdx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: Create attributes
openapi: openapi/admin.yml post /attributes
openapi: "POST /attributes"
---

import { RateLimitBadge } from "../../../components/rate-limit-badge.jsx";
Expand Down
2 changes: 1 addition & 1 deletion admin-api/endpoints/attributes/delete-attributes.mdx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: Delete attributes
openapi: openapi/admin.yml delete /attributes
openapi: "DELETE /attributes"
---

import { RateLimitBadge } from "../../../components/rate-limit-badge.jsx";
Expand Down
2 changes: 1 addition & 1 deletion admin-api/endpoints/attributes/get-an-attribute.mdx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: Get an attribute
openapi: openapi/admin.yml get /attributes/{id}
openapi: "GET /attributes/{id}"
---

import { RateLimitBadge } from "../../../components/rate-limit-badge.jsx";
Expand Down
2 changes: 1 addition & 1 deletion admin-api/endpoints/attributes/list-attributes.mdx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: List attributes
openapi: openapi/admin.yml get /attributes
openapi: "GET /attributes"
---

import { RateLimitBadge } from "../../../components/rate-limit-badge.jsx";
Expand Down
2 changes: 1 addition & 1 deletion admin-api/endpoints/attributes/update-attributes.mdx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: Update attributes
openapi: openapi/admin.yml patch /attributes
openapi: "PATCH /attributes"
---

import { RateLimitBadge } from "../../../components/rate-limit-badge.jsx";
Expand Down
2 changes: 1 addition & 1 deletion admin-api/endpoints/leaderboards/create-leaderboards.mdx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: Create leaderboards
openapi: openapi/admin.yml post /leaderboards
openapi: "POST /leaderboards"
---

import { RateLimitBadge } from "../../../components/rate-limit-badge.jsx";
Expand Down
2 changes: 1 addition & 1 deletion admin-api/endpoints/leaderboards/delete-leaderboards.mdx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: Delete leaderboards
openapi: openapi/admin.yml delete /leaderboards
openapi: "DELETE /leaderboards"
---

import { RateLimitBadge } from "../../../components/rate-limit-badge.jsx";
Expand Down
2 changes: 1 addition & 1 deletion admin-api/endpoints/leaderboards/get-a-leaderboard.mdx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: Get a leaderboard
openapi: openapi/admin.yml get /leaderboards/{id}
openapi: "GET /leaderboards/{id}"
---

import { RateLimitBadge } from "../../../components/rate-limit-badge.jsx";
Expand Down
2 changes: 1 addition & 1 deletion admin-api/endpoints/leaderboards/list-leaderboards.mdx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: List leaderboards
openapi: openapi/admin.yml get /leaderboards
openapi: "GET /leaderboards"
---

import { RateLimitBadge } from "../../../components/rate-limit-badge.jsx";
Expand Down
2 changes: 1 addition & 1 deletion admin-api/endpoints/leaderboards/update-leaderboards.mdx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: Update leaderboards
openapi: openapi/admin.yml patch /leaderboards
openapi: "PATCH /leaderboards"
---

import { RateLimitBadge } from "../../../components/rate-limit-badge.jsx";
Expand Down
2 changes: 1 addition & 1 deletion admin-api/endpoints/metrics/create-metrics.mdx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: Create metrics
openapi: openapi/admin.yml post /metrics
openapi: "POST /metrics"
---

import { RateLimitBadge } from "../../../components/rate-limit-badge.jsx";
Expand Down
2 changes: 1 addition & 1 deletion admin-api/endpoints/metrics/delete-metrics.mdx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: Delete metrics
openapi: openapi/admin.yml delete /metrics
openapi: "DELETE /metrics"
---

import { RateLimitBadge } from "../../../components/rate-limit-badge.jsx";
Expand Down
2 changes: 1 addition & 1 deletion admin-api/endpoints/metrics/get-a-metric.mdx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: Get a metric by ID
openapi: openapi/admin.yml get /metrics/{id}
openapi: "GET /metrics/{id}"
---

import { RateLimitBadge } from "../../../components/rate-limit-badge.jsx";
Expand Down
2 changes: 1 addition & 1 deletion admin-api/endpoints/metrics/list-metrics.mdx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: List metrics
openapi: openapi/admin.yml get /metrics
openapi: "GET /metrics"
---

import { RateLimitBadge } from "../../../components/rate-limit-badge.jsx";
Expand Down
2 changes: 1 addition & 1 deletion admin-api/endpoints/metrics/update-metrics.mdx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: Update metrics
openapi: openapi/admin.yml patch /metrics
openapi: "PATCH /metrics"
---

import { RateLimitBadge } from "../../../components/rate-limit-badge.jsx";
Expand Down
2 changes: 1 addition & 1 deletion admin-api/endpoints/points/create-boosts.mdx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: Create points boosts
openapi: openapi/admin.yml post /points/{systemId}/boosts
openapi: "POST /points/{systemId}/boosts"
---

import { RateLimitBadge } from "../../../components/rate-limit-badge.jsx";
Expand Down
2 changes: 1 addition & 1 deletion admin-api/endpoints/points/create-levels.mdx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: Create points levels
openapi: openapi/admin.yml post /points/{systemId}/levels
openapi: "POST /points/{systemId}/levels"
---

import { RateLimitBadge } from "../../../components/rate-limit-badge.jsx";
Expand Down
2 changes: 1 addition & 1 deletion admin-api/endpoints/points/create-points-systems.mdx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: Create points systems
openapi: openapi/admin.yml post /points
openapi: "POST /points"
---

import { RateLimitBadge } from "../../../components/rate-limit-badge.jsx";
Expand Down
2 changes: 1 addition & 1 deletion admin-api/endpoints/points/create-points-triggers.mdx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: Create points triggers
openapi: openapi/admin.yml post /points/{systemId}/triggers
openapi: "POST /points/{systemId}/triggers"
---

import { RateLimitBadge } from "../../../components/rate-limit-badge.jsx";
Expand Down
2 changes: 1 addition & 1 deletion admin-api/endpoints/points/delete-boosts.mdx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: Delete multiple points boosts
openapi: openapi/admin.yml delete /points/{systemId}/boosts
openapi: "DELETE /points/{systemId}/boosts"
---

import { RateLimitBadge } from "../../../components/rate-limit-badge.jsx";
Expand Down
2 changes: 1 addition & 1 deletion admin-api/endpoints/points/delete-levels.mdx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: Delete multiple points levels
openapi: openapi/admin.yml delete /points/{systemId}/levels
openapi: "DELETE /points/{systemId}/levels"
---

import { RateLimitBadge } from "../../../components/rate-limit-badge.jsx";
Expand Down
2 changes: 1 addition & 1 deletion admin-api/endpoints/points/delete-points-systems.mdx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: Delete points systems
openapi: openapi/admin.yml delete /points
openapi: "DELETE /points"
---

import { RateLimitBadge } from "../../../components/rate-limit-badge.jsx";
Expand Down
2 changes: 1 addition & 1 deletion admin-api/endpoints/points/delete-points-triggers.mdx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: Delete points triggers
openapi: openapi/admin.yml delete /points/{systemId}/triggers
openapi: "DELETE /points/{systemId}/triggers"
---

import { RateLimitBadge } from "../../../components/rate-limit-badge.jsx";
Expand Down
2 changes: 1 addition & 1 deletion admin-api/endpoints/points/get-a-boost.mdx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: Get a points boost by ID
openapi: openapi/admin.yml get /points/{systemId}/boosts/{id}
openapi: "GET /points/{systemId}/boosts/{id}"
---

import { RateLimitBadge } from "../../../components/rate-limit-badge.jsx";
Expand Down
2 changes: 1 addition & 1 deletion admin-api/endpoints/points/get-a-level.mdx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: Get a points level by ID
openapi: openapi/admin.yml get /points/{systemId}/levels/{id}
openapi: "GET /points/{systemId}/levels/{id}"
---

import { RateLimitBadge } from "../../../components/rate-limit-badge.jsx";
Expand Down
2 changes: 1 addition & 1 deletion admin-api/endpoints/points/get-a-points-system.mdx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: Get a points system by ID
openapi: openapi/admin.yml get /points/{id}
openapi: "GET /points/{id}"
---

import { RateLimitBadge } from "../../../components/rate-limit-badge.jsx";
Expand Down
2 changes: 1 addition & 1 deletion admin-api/endpoints/points/get-a-points-trigger.mdx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: Get a points trigger by ID
openapi: openapi/admin.yml get /points/{systemId}/triggers/{id}
openapi: "GET /points/{systemId}/triggers/{id}"
---

import { RateLimitBadge } from "../../../components/rate-limit-badge.jsx";
Expand Down
2 changes: 1 addition & 1 deletion admin-api/endpoints/points/list-boosts.mdx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: List points boosts
openapi: openapi/admin.yml get /points/{systemId}/boosts
openapi: "GET /points/{systemId}/boosts"
---

import { RateLimitBadge } from "../../../components/rate-limit-badge.jsx";
Expand Down
2 changes: 1 addition & 1 deletion admin-api/endpoints/points/list-levels.mdx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: List points levels
openapi: openapi/admin.yml get /points/{systemId}/levels
openapi: "GET /points/{systemId}/levels"
---

import { RateLimitBadge } from "../../../components/rate-limit-badge.jsx";
Expand Down
2 changes: 1 addition & 1 deletion admin-api/endpoints/points/list-points-systems.mdx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: List points systems
openapi: openapi/admin.yml get /points
openapi: "GET /points"
---

import { RateLimitBadge } from "../../../components/rate-limit-badge.jsx";
Expand Down
2 changes: 1 addition & 1 deletion admin-api/endpoints/points/list-points-triggers.mdx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: List points triggers
openapi: openapi/admin.yml get /points/{systemId}/triggers
openapi: "GET /points/{systemId}/triggers"
---

import { RateLimitBadge } from "../../../components/rate-limit-badge.jsx";
Expand Down
2 changes: 1 addition & 1 deletion admin-api/endpoints/points/update-boosts.mdx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: Update multiple points boosts
openapi: openapi/admin.yml patch /points/{systemId}/boosts
openapi: "PATCH /points/{systemId}/boosts"
---

import { RateLimitBadge } from "../../../components/rate-limit-badge.jsx";
Expand Down
2 changes: 1 addition & 1 deletion admin-api/endpoints/points/update-levels.mdx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: Update multiple points levels
openapi: openapi/admin.yml patch /points/{systemId}/levels
openapi: "PATCH /points/{systemId}/levels"
---

import { RateLimitBadge } from "../../../components/rate-limit-badge.jsx";
Expand Down
2 changes: 1 addition & 1 deletion admin-api/endpoints/points/update-points-systems.mdx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: Update points systems
openapi: openapi/admin.yml patch /points
openapi: "PATCH /points"
---

import { RateLimitBadge } from "../../../components/rate-limit-badge.jsx";
Expand Down
2 changes: 1 addition & 1 deletion admin-api/endpoints/points/update-points-triggers.mdx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: Update points triggers
openapi: openapi/admin.yml patch /points/{systemId}/triggers
openapi: "PATCH /points/{systemId}/triggers"
---

import { RateLimitBadge } from "../../../components/rate-limit-badge.jsx";
Expand Down
2 changes: 1 addition & 1 deletion admin-api/endpoints/streaks/grant-freezes.mdx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: Create streak freezes for multiple users
openapi: openapi/admin.yml post /streaks/freezes
openapi: "POST /streaks/freezes"
---

import { RateLimitBadge } from "../../../components/rate-limit-badge.jsx";
Expand Down
2 changes: 1 addition & 1 deletion admin-api/endpoints/streaks/restore-streaks.mdx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: Restore streaks for multiple users
openapi: openapi/admin.yml post /streaks/restore
openapi: "POST /streaks/restore"
---

import { RateLimitBadge } from "../../../components/rate-limit-badge.jsx";
Expand Down
2 changes: 1 addition & 1 deletion admin-api/endpoints/tenants/create-tenants.mdx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: Create tenants
openapi: openapi/admin.yml post /tenants
openapi: "POST /tenants"
---

import { RateLimitBadge } from "../../../components/rate-limit-badge.jsx";
Expand Down
2 changes: 1 addition & 1 deletion admin-api/endpoints/tenants/delete-tenants.mdx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: Delete tenants
openapi: openapi/admin.yml delete /tenants
openapi: "DELETE /tenants"
---

import { RateLimitBadge } from "../../../components/rate-limit-badge.jsx";
Expand Down
2 changes: 1 addition & 1 deletion admin-api/endpoints/tenants/get-a-tenant.mdx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: Get a tenant
openapi: openapi/admin.yml get /tenants/{id}
openapi: "GET /tenants/{id}"
---

import { RateLimitBadge } from "../../../components/rate-limit-badge.jsx";
Expand Down
2 changes: 1 addition & 1 deletion admin-api/endpoints/tenants/list-tenants.mdx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: List tenants
openapi: openapi/admin.yml get /tenants
openapi: "GET /tenants"
---

import { RateLimitBadge } from "../../../components/rate-limit-badge.jsx";
Expand Down
2 changes: 1 addition & 1 deletion admin-api/endpoints/tenants/update-tenants.mdx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: Update tenants
openapi: openapi/admin.yml patch /tenants
openapi: "PATCH /tenants"
---

import { RateLimitBadge } from "../../../components/rate-limit-badge.jsx";
Expand Down
2 changes: 1 addition & 1 deletion api-reference/endpoints/achievements/all-achievements.mdx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: Get all achievements and their completion stats
openapi: openapi/application.yml get /achievements
openapi: "GET /achievements"
---

import { RateLimitBadge } from "../../../components/rate-limit-badge.jsx";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: Mark an achievement as completed
openapi: openapi/application.yml post /achievements/{key}/complete
openapi: "POST /achievements/{key}/complete"
---

import { RateLimitBadge } from "../../../components/rate-limit-badge.jsx";
Expand Down
Loading
Loading