# WordQuest - Full API & Platform Reference > Extended documentation for LLM context import. Use this to understand WordQuest's > API surface, data models, error codes, and integration patterns. > > For a concise overview, see [llms.txt](https://wordquest.solanalink.jp/llms.txt). --- ## Platform Overview WordQuest is a Japanese learning platform for JLPT N5 to N1 preparation. - **Live site**: https://wordquest.solanalink.jp - **146 courses**, 8,200+ vocabulary words, 500+ grammar patterns - **8 locales**: en, zh, ja, ko, vi, id, zh-TW, zh-HK - **Mobile apps**: iOS (App Store) + Android (Google Play) via Capacitor 8 - **AI Tutor (Sage)**: Multi-modal chat, speaking practice, writing correction --- ## Authentication {#auth} ### OAuth Providers Google, Apple, Discord, LINE, Twitter, Telegram ### Login Flow 1. `POST /api/auth/login` with `{ email, password }` returns a session cookie 2. `GET /api/auth/me` returns the current user session 3. All mutation endpoints require authentication via `requireAuth()` ### Token Errors {#auth-token-expired} - `TOKEN_EXPIRED` (code 1003): Session expired. Re-authenticate via `/api/auth/login` - `TOKEN_INVALID` (code 1004): Token is malformed. Obtain a new token ### Authorization Errors {#auth-unauthorized} - `UNAUTHORIZED` (code 1001): No valid session. Authenticate first - `FORBIDDEN` (code 1002): Authenticated but insufficient permissions ### Forbidden Errors {#auth-forbidden} - Requires higher user tier or admin role - Tier progression: Ronin -> Ashigaru -> Samurai -> Hatamoto -> Daimyo -> Shogun --- ## API Response Format ### Success Response ```json { "success": true, "message": "Optional message", "data": { ... }, "timestamp": "2026-04-12T00:00:00.000Z" } ``` ### Error Response ```json { "success": false, "error": "Human-readable error message", "code": 3001, "request_id": "uuid-v4", "is_retriable": false, "doc_url": "https://wordquest.solanalink.jp/llms-full.txt#resource-not-found", "alternative_action": "Verify resource ID via the list endpoint", "details": { ... }, "timestamp": "2026-04-12T00:00:00.000Z" } ``` ### Self-Healing Error Fields - `request_id`: UUID for tracing and support - `is_retriable`: Whether the agent should retry the request - `retry_after`: Seconds to wait before retrying (present on 429 and 5xx) - `doc_url`: Link to relevant section in this document - `alternative_action`: Suggested workaround for the agent --- ## Error Code Reference {#errors} ### Authentication Errors (1000-1999) | Code | Name | HTTP | Retriable | Action | |------|------|------|-----------|--------| | 1001 | UNAUTHORIZED | 401 | No | Authenticate via OAuth or POST /api/auth/login | | 1002 | FORBIDDEN | 403 | No | Requires higher tier or admin role | | 1003 | TOKEN_EXPIRED | 401 | Yes | Re-authenticate to obtain new session | | 1004 | TOKEN_INVALID | 401 | No | Obtain a new token via login | | 1005 | SESSION_EXPIRED | 401 | Yes | Re-authenticate to obtain new session | ### Validation Errors (2000-2999) {#validation} | Code | Name | HTTP | Retriable | Action | |------|------|------|-----------|--------| | 2001 | VALIDATION_ERROR | 400 | No | See details.fieldErrors for specific issues | | 2002 | INVALID_INPUT | 400 | No | Check request body against expected schema | | 2003 | MISSING_REQUIRED_FIELD | 400 | No | Include all required fields | | 2004 | INVALID_FORMAT | 400 | No | Check field format (email, date, etc.) | ### Resource Errors (3000-3999) {#resource-not-found} | Code | Name | HTTP | Retriable | Action | |------|------|------|-----------|--------| | 3001 | NOT_FOUND | 404 | No | Verify resource ID via the list endpoint | | 3002 | ALREADY_EXISTS | 409 | No | Fetch existing resource before creating | | 3003 | CONFLICT | 409 | No | Resolve conflict then retry | ### Database Errors (4000-4999) {#database-error} | Code | Name | HTTP | Retriable | Action | |------|------|------|-----------|--------| | 4001 | DATABASE_ERROR | 500 | Yes | Retry after 5 seconds | | 4002 | QUERY_FAILED | 500 | Yes | Retry after 5 seconds | | 4003 | CONNECTION_ERROR | 500 | Yes | Retry after 10 seconds | ### External Service Errors (5000-5999) {#external-api} | Code | Name | HTTP | Retriable | Action | |------|------|------|-----------|--------| | 5001 | EXTERNAL_API_ERROR | 502 | Yes | External service unavailable, retry after 30s | | 5002 | OAUTH_ERROR | 401 | No | Re-initiate OAuth flow | | 5003 | EMAIL_SERVICE_ERROR | 502 | Yes | Email delivery failed, retry after 30s | ### Rate Limiting (6000-6999) {#rate-limiting} | Code | Name | HTTP | Retriable | Action | |------|------|------|-----------|--------| | 6001 | RATE_LIMIT_EXCEEDED | 429 | Yes | Check retry_after header, reduce frequency | | 6002 | TOO_MANY_REQUESTS | 429 | Yes | Check retry_after header, reduce frequency | ### Internal Errors (9000-9999) {#internal-error} | Code | Name | HTTP | Retriable | Action | |------|------|------|-----------|--------| | 9001 | INTERNAL_SERVER_ERROR | 500 | Yes | Retry after 10 seconds, report if persistent | | 9999 | UNKNOWN_ERROR | 500 | Yes | Retry after 10 seconds, report if persistent | --- ## API Endpoints {#endpoints} ### Learning Content #### Courses Courses are the core learning unit. Each course covers a topic at a specific JLPT level. - **Browse courses**: Navigate to `/{locale}/course` (web) or `/{locale}/course/{courseId}` for a specific course - **Course IDs**: 0-48 (49 course groups, each containing multiple sub-courses totaling 146) - **JLPT Levels**: N5 (beginner) -> N4 -> N3 -> N2 -> N1 (advanced) #### Vocabulary - `/{locale}/vocabulary` — Browse all vocabulary words - 8,200+ words with Japanese, romaji, translations in 8 languages - Audio pronunciation files available for all words #### Grammar - `/{locale}/grammar` — Browse 500+ grammar patterns - Organized by JLPT level with example sentences #### Practice Hub - `/{locale}/practice` — Listening, reading, and mock test practice - Adaptive difficulty based on user progress ### Analytics & Progress | Method | Endpoint | Auth | Description | |--------|----------|------|-------------| | GET | /api/analytics/summary | Yes | Overall learning statistics | | GET | /api/analytics/activity | Yes | Daily activity heatmap data | | GET | /api/analytics/progress | Yes | Course completion progress | | GET | /api/analytics/quizzes | Yes | Quiz performance history | ### Study History | Method | Endpoint | Auth | Description | |--------|----------|------|-------------| | GET | /api/study-history | Yes | Get study history entries | | POST | /api/study-history | Yes | Record a study session | ### Study Strategy | Method | Endpoint | Auth | Description | |--------|----------|------|-------------| | GET | /api/study-strategy | Yes | Get current study strategy | | POST | /api/study-strategy | Yes | Create study strategy | | PUT | /api/study-strategy | Yes | Update study strategy | | DELETE | /api/study-strategy | Yes | Delete study strategy | ### Quiz System | Method | Endpoint | Auth | Description | |--------|----------|------|-------------| | GET | /api/quiz | Yes | List available quizzes | | POST | /api/quiz/start | Yes | Start a quiz session | | POST | /api/quiz/submit | Yes | Submit quiz answers | | GET | /api/quiz/history | Yes | Quiz attempt history | ### Watchlist | Method | Endpoint | Auth | Description | |--------|----------|------|-------------| | GET | /api/watchlist | Yes | Get saved vocabulary items | | POST | /api/watchlist | Yes | Add item to watchlist | | PUT | /api/watchlist | Yes | Update watchlist item | | DELETE | /api/watchlist | Yes | Remove from watchlist | ### Authentication | Method | Endpoint | Auth | Description | |--------|----------|------|-------------| | POST | /api/auth/register | No | Create new account | | POST | /api/auth/login | No | Email/password login | | GET | /api/auth/me | Yes | Get current session | | POST | /api/auth/logout | Yes | End session | | POST | /api/auth/change-password | Yes | Change password | | POST | /api/auth/forgot-password | No | Request password reset | | POST | /api/auth/reset-password | No | Reset with token | | POST | /api/auth/verify-email | No | Verify email address | | POST | /api/auth/delete-account | Yes | Delete account | #### Native OAuth (Mobile) | Method | Endpoint | Auth | Description | |--------|----------|------|-------------| | POST | /api/auth/google-native | No | Google native sign-in | | POST | /api/auth/apple-native | No | Apple native sign-in | | POST | /api/auth/twitter-native | No | Twitter native sign-in | | GET | /api/auth/telegram-native | No | Telegram auth | | POST | /api/auth/exchange-native-code | No | Exchange one-time code for session | ### Two-Factor Authentication | Method | Endpoint | Auth | Description | |--------|----------|------|-------------| | GET | /api/2fa | Yes | Get 2FA status | | POST | /api/2fa | Yes | Setup 2FA (get QR code) | | POST | /api/2fa/enable | Yes | Enable 2FA with TOTP code | | POST | /api/2fa/verify | No | Verify 2FA during login | ### User Profile | Method | Endpoint | Auth | Description | |--------|----------|------|-------------| | GET | /api/profile | Yes | Get own profile | | PUT | /api/profile | Yes | Update profile | | POST | /api/profile/avatar | Yes | Upload avatar image | | DELETE | /api/profile/avatar | Yes | Remove avatar | | GET | /api/profile/chronicle | Yes | Get user chronicle/timeline | #### AI Avatar | Method | Endpoint | Auth | Description | |--------|----------|------|-------------| | GET | /api/profile/ai-avatar | Yes | Get current AI avatar | | POST | /api/profile/ai-avatar | Yes | Set AI avatar | | POST | /api/profile/ai-avatar/generate | Yes | Generate new AI avatar (DALL-E 3) | | GET | /api/profile/ai-avatar/history | Yes | Avatar generation history | | POST | /api/profile/ai-avatar/use | Yes | Use a previously generated avatar | ### Social: Users | Method | Endpoint | Auth | Description | |--------|----------|------|-------------| | GET | /api/users/{userId} | No | Get user public profile | | GET | /api/users/{userId}/follow | Yes | Check follow status | | POST | /api/users/{userId}/follow | Yes | Follow a user | | DELETE | /api/users/{userId}/follow | Yes | Unfollow a user | | GET | /api/users/{userId}/followers | No | List followers | | GET | /api/users/{userId}/following | No | List following | ### Social: Tavern (Community Feed) | Method | Endpoint | Auth | Description | |--------|----------|------|-------------| | GET | /api/tavern/posts | No | List posts (Hot/New/Top) | | POST | /api/tavern/posts | Yes | Create post | | GET | /api/tavern/posts/{id} | No | Get single post | | PATCH | /api/tavern/posts/{id} | Yes | Update post | | DELETE | /api/tavern/posts/{id} | Yes | Delete post | | POST | /api/tavern/posts/{id}/cheer | Yes | Cheer a post | | GET | /api/tavern/posts/{id}/comments | No | List comments | | POST | /api/tavern/posts/{id}/comments | Yes | Add comment | | GET | /api/tavern/posts/{id}/related | No | Related posts | | POST | /api/tavern/posts/{id}/tip | Yes | Tip post author (Neko Coins) | ### Social: Events | Method | Endpoint | Auth | Description | |--------|----------|------|-------------| | GET | /api/tavern/events | No | List events | | POST | /api/tavern/events | Yes | Create event (costs Neko Coins) | | GET | /api/tavern/events/{id} | No | Get event details | | PUT | /api/tavern/events/{id} | Yes | Update event | | DELETE | /api/tavern/events/{id} | Yes | Cancel event | | POST | /api/tavern/events/{id}/join | Yes | Join event | | DELETE | /api/tavern/events/{id}/join | Yes | Leave event | | GET | /api/tavern/events/{id}/participants | No | List participants | ### Social: Messages (Secret Scrolls) | Method | Endpoint | Auth | Description | |--------|----------|------|-------------| | GET | /api/messages | Yes | List conversations | | POST | /api/messages | Yes | Send message | | GET | /api/messages/count | Yes | Unread count | | GET | /api/messages/{userId} | Yes | Conversation with user | | POST | /api/messages/{userId} | Yes | Send to specific user | | GET | /api/messages/block | Yes | List blocked users | | POST | /api/messages/block | Yes | Block user | | DELETE | /api/messages/block | Yes | Unblock user | | POST | /api/messages/report | Yes | Report message | ### Gamification: Isekai | Method | Endpoint | Auth | Description | |--------|----------|------|-------------| | GET | /api/isekai/stats | Yes | Get isekai stats (tier, coins, XP) | | POST | /api/isekai/award-points | Yes | Award XP points | #### Neko Coin Economy - Earn through study sessions, quizzes, daily quests, streaks - Spend on AI tutor questions, event creation, gacha pulls, duels, avatar generation - View balance via GET /api/isekai/stats - Transaction history via GET /api/coin-transactions ### Gamification: Duels (PvP) | Method | Endpoint | Auth | Description | |--------|----------|------|-------------| | GET | /api/duels | Yes | List available duels | | POST | /api/duels | Yes | Create duel (with wager) | | POST | /api/duels/{duelId}/join | Yes | Join a duel | | POST | /api/duels/{duelId}/start | Yes | Start duel | | GET | /api/duels/{duelId}/questions | Yes | Get duel questions | | POST | /api/duels/{duelId}/submit | Yes | Submit answers | | POST | /api/duels/{duelId}/settle | Yes | Settle duel results | | POST | /api/duels/{duelId}/cancel | Yes | Cancel duel | ### Gamification: Shrine (Gacha) | Method | Endpoint | Auth | Description | |--------|----------|------|-------------| | GET | /api/shrine/banner | No | Current gacha banner | | POST | /api/shrine/pull | Yes | Pull gacha (costs Neko Coins) | | GET | /api/shrine/inventory | Yes | Owned items | | GET | /api/shrine/equip | Yes | Currently equipped items | | POST | /api/shrine/equip | Yes | Equip item | | DELETE | /api/shrine/equip | Yes | Unequip item | | GET | /api/shrine/history | Yes | Pull history | Item rarities: Common (C) -> Rare (R) -> Super Rare (SR) -> SSR SSR pity guarantee at 100 pulls. ### Gamification: Squads (Teams) | Method | Endpoint | Auth | Description | |--------|----------|------|-------------| | GET | /api/squads | No | List squads | | POST | /api/squads | Yes | Create squad | | GET | /api/squads/my | Yes | Get own squad | | POST | /api/squads/join | Yes | Join squad by code | | POST | /api/squads/leave | Yes | Leave squad | | GET | /api/squads/{squadId} | No | Get squad details | | DELETE | /api/squads/{squadId} | Yes | Disband squad | | POST | /api/squads/{squadId}/transfer | Yes | Transfer leadership | | GET | /api/squads/{squadId}/voice-token | Yes | Get Agora voice token | ### AI Tutor: Sage | Method | Endpoint | Auth | Description | |--------|----------|------|-------------| | POST | /api/ai/mentor/ask | Yes | Ask Sage a question | | PATCH | /api/ai/mentor/ask | Yes | Continue conversation | | GET | /api/ai/sage/status | Yes | Sage usage status | | GET | /api/ai/sage/ledger | Yes | AI usage history | | POST | /api/ai/speaking/chat | Yes | Speaking practice | | POST | /api/ai/speaking/evaluate | Yes | Evaluate pronunciation | | POST | /api/ai/writing/correct | Yes | Writing correction | Billing: 3 free questions/day, then 50 Neko Coins per question. ### Notifications & Push | Method | Endpoint | Auth | Description | |--------|----------|------|-------------| | GET | /api/notifications | Yes | List notifications | | POST | /api/notifications | Yes | Mark as read | | GET | /api/notifications/count | Yes | Unread count | | POST | /api/push/device-token | Yes | Register device for push | | DELETE | /api/push/device-token | Yes | Unregister device | | PATCH | /api/push/preferences | Yes | Update push preferences | ### Economy: Recharge & Withdrawal | Method | Endpoint | Auth | Description | |--------|----------|------|-------------| | GET | /api/recharge/packages | No | Available Neko Coin packages | | POST | /api/recharge/create-order | Yes | Create recharge order | | POST | /api/recharge/verify-tx | Yes | Verify blockchain payment | | GET | /api/recharge/orders | Yes | Order history | | GET | /api/withdrawal/eligibility | Yes | Check withdrawal eligibility | | GET | /api/withdrawal/preview | Yes | Preview withdrawal amount | | POST | /api/withdrawal | Yes | Request withdrawal | ### Other | Method | Endpoint | Auth | Description | |--------|----------|------|-------------| | GET | /api/feedback | Yes | Get submitted feedback | | POST | /api/feedback | Yes | Submit feedback | | POST | /api/upload | Yes | Upload file | | GET | /api/vocab-audio | No | Get vocabulary audio URL | | GET | /api/download | No | App download redirect | --- ## Data Models {#models} ### User - `id`: String (cuid) - `name`: Display name - `email`: Email address - `image`: Avatar URL - `tier`: Ronin | Ashigaru | Samurai | Hatamoto | Daimyo | Shogun - `nekoCoins`: Integer (in-app currency balance) - `xp`: Integer (experience points) - `streak`: Integer (consecutive study days) - `locale`: Preferred language ### Course - `id`: Integer (0-48) - `title`: Course title (localized) - `jlptLevel`: N5 | N4 | N3 | N2 | N1 - `vocabularyCount`: Number of words - `hasAudio`: Boolean ### Vocabulary Word - `japanese`: Japanese text (kanji/kana) - `romaji`: Romanized pronunciation - `translation`: Meaning (localized to user's language) - `explanation`: Usage explanation - `exampleSentence`: Example in Japanese - `audioUrl`: Pronunciation audio URL ### Grammar Pattern - `pattern`: Grammar pattern - `jlptLevel`: N5 | N4 | N3 | N2 | N1 - `meaning`: Explanation (localized) - `examples`: Array of example sentences ### Post (Tavern) - `id`: Integer - `title`: Post title - `content`: Post body (Markdown) - `authorId`: User ID - `cheers`: Integer (like count) - `commentCount`: Integer - `createdAt`: ISO 8601 timestamp ### Duel - `id`: Integer - `challengerId`: User ID - `opponentId`: User ID (nullable until joined) - `wager`: Integer (Neko Coins) - `status`: OPEN | IN_PROGRESS | COMPLETED | CANCELLED - `winnerId`: User ID (after settlement) --- ## JLPT Level System {#jlpt} | Level | Difficulty | Vocabulary | Grammar | Description | |-------|-----------|------------|---------|-------------| | N5 | Beginner | ~800 | ~80 | Basic Japanese, hiragana/katakana | | N4 | Elementary | ~1,500 | ~200 | Basic conversation, simple kanji | | N3 | Intermediate | ~3,750 | ~350 | Daily conversation, moderate kanji | | N2 | Upper-Intermediate | ~6,000 | ~450 | Newspapers, workplace Japanese | | N1 | Advanced | ~10,000 | ~500+ | Academic/professional fluency | --- ## Tier System (Isekai) {#tiers} | Tier | Required XP | Perks | |------|------------|-------| | Ronin | 0 | Basic access | | Ashigaru | 500 | Extended daily quests | | Samurai | 2,000 | Custom avatar frames | | Hatamoto | 5,000 | AI avatar generation | | Daimyo | 15,000 | Premium features | | Shogun | 50,000 | All features unlocked | --- ## Neko Coin Economy {#coins} ### Earning - Complete course lesson: +10 coins - Quiz (grade-dependent): +5 to +50 coins - Daily login streak: +5 per day - Win duel: wager amount from opponent - Referral bonus: +100 coins ### Spending - AI Sage question: 50 coins (after 3 free/day) - Shrine gacha pull: 100 coins (10-pull: 900) - Create duel: wager amount (10-1000) - Create event: 50 coins - AI avatar generation: 200 coins - Streak protection: 50 coins --- ## MCP Servers {#mcp} WordQuest provides 2 MCP servers for Claude Code integration: ### Tavern Server (91 tools) Community management, social features, game systems: - Post CRUD, comments, cheers, tips - Event management, participants - Duel lifecycle (create, join, settle) - Shrine gacha (pull, inventory, equip) - Squad management, membership - User profiles, stats, moderation - Sage AI usage tracking - Notification management ### Push Server (20 tools) Push notification management: - Device token registration - Notification preferences - Daily reminder scheduling - Test notification sending --- ## Locales {#locales} | Code | Language | URL Prefix | |------|----------|------------| | zh | Simplified Chinese | / (default, no prefix) | | en | English | /en | | ja | Japanese | /ja | | ko | Korean | /ko | | vi | Vietnamese | /vi | | id | Indonesian | /id | | zh-TW | Traditional Chinese (Taiwan) | /zh-TW | | zh-HK | Traditional Chinese (Hong Kong) | /zh-HK | All page URLs follow pattern: `https://wordquest.solanalink.jp/{locale}/{page}` Default locale (zh) has no prefix: `https://wordquest.solanalink.jp/{page}` --- ## Resource Conflict Resolution {#resource-conflict} When receiving ALREADY_EXISTS (3002) or CONFLICT (3003): 1. Fetch the existing resource via the corresponding GET endpoint 2. Compare with intended changes 3. Either update the existing resource (PUT/PATCH) or use a different identifier --- _Last updated: 2026-04-12_