> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/monkeytypegame/monkeytype/llms.txt
> Use this file to discover all available pages before exploring further.

# API Endpoints

> Complete reference for Monkeytype API endpoints

## Users

### Get User Data

Retrieve complete user profile and settings.

<CodeGroup>
  ```bash cURL theme={null}
  curl https://api.monkeytype.com/users \
    -H "Authorization: Bearer YOUR_TOKEN"
  ```

  ```typescript TypeScript theme={null}
  const response = await fetch('https://api.monkeytype.com/users', {
    headers: { 'Authorization': `Bearer ${token}` }
  });
  const { data } = await response.json();
  ```
</CodeGroup>

<ResponseField name="data" type="object">
  <Expandable title="User object">
    <ResponseField name="uid" type="string" required>
      User's unique identifier
    </ResponseField>

    <ResponseField name="name" type="string" required>
      Username
    </ResponseField>

    <ResponseField name="email" type="string" required>
      User's email address
    </ResponseField>

    <ResponseField name="addedAt" type="number" required>
      Account creation timestamp
    </ResponseField>

    <ResponseField name="personalBests" type="object" required>
      Personal best records by mode
    </ResponseField>

    <ResponseField name="completedTests" type="number">
      Total number of completed tests
    </ResponseField>

    <ResponseField name="startedTests" type="number">
      Total number of started tests
    </ResponseField>

    <ResponseField name="timeTyping" type="number">
      Total seconds spent typing
    </ResponseField>

    <ResponseField name="xp" type="number">
      Total XP earned
    </ResponseField>

    <ResponseField name="streak" type="object">
      Current and max streak information
    </ResponseField>

    <ResponseField name="isPremium" type="boolean">
      Premium subscription status
    </ResponseField>

    <ResponseField name="inboxUnreadSize" type="number" required>
      Count of unread inbox messages
    </ResponseField>
  </Expandable>
</ResponseField>

### Create User

Register a new user account.

```bash theme={null}
curl -X POST https://api.monkeytype.com/users/signup \
  -H "Content-Type: application/json" \
  -d '{
    "name": "username",
    "email": "user@example.com",
    "captcha": "CAPTCHA_TOKEN"
  }'
```

<ParamField body="name" type="string" required>
  Desired username (1-16 characters, alphanumeric, underscores, hyphens, dots)
</ParamField>

<ParamField body="email" type="string">
  User's email address
</ParamField>

<ParamField body="captcha" type="string" required>
  Google reCAPTCHA token
</ParamField>

### Get User Profile

Retrieve public profile of any user.

```bash theme={null}
curl "https://api.monkeytype.com/users/{uidOrName}/profile?isUid=false"
```

<ParamField path="uidOrName" type="string" required>
  Username or user ID
</ParamField>

<ParamField query="isUid" type="boolean" default="false">
  Whether the path parameter is a UID (true) or username (false)
</ParamField>

### Update Username

Change username (once per 30 days).

```bash theme={null}
curl -X PATCH https://api.monkeytype.com/users/name \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name": "newusername"}'
```

<Warning>
  Requires fresh token (issued within last 60 seconds). Limited to once per 30 days.
</Warning>

***

## Results

### Submit Test Result

Submit a completed typing test result.

```bash theme={null}
curl -X POST https://api.monkeytype.com/results \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "result": {
      "wpm": 85.5,
      "acc": 96.8,
      "mode": "time",
      "mode2": "60",
      "language": "english",
      "timestamp": 1234567890,
      "testDuration": 60,
      "consistency": 78.5,
      "rawWpm": 90.2,
      "hash": "RESULT_HASH"
    }
  }'
```

<ParamField body="result" type="object" required>
  <Expandable title="CompletedEvent object">
    <ParamField body="wpm" type="number" required>
      Words per minute
    </ParamField>

    <ParamField body="rawWpm" type="number" required>
      Raw WPM (includes errors)
    </ParamField>

    <ParamField body="acc" type="number" required>
      Accuracy percentage (0-100)
    </ParamField>

    <ParamField body="mode" type="string" required>
      Test mode: "time", "words", "quote", "zen", "custom"
    </ParamField>

    <ParamField body="mode2" type="string" required>
      Mode variant (e.g., "60" for 60-second test)
    </ParamField>

    <ParamField body="language" type="string" required>
      Language code (e.g., "english")
    </ParamField>

    <ParamField body="timestamp" type="number" required>
      Test completion timestamp
    </ParamField>

    <ParamField body="testDuration" type="number" required>
      Test duration in seconds
    </ParamField>

    <ParamField body="consistency" type="number" required>
      Consistency percentage
    </ParamField>

    <ParamField body="hash" type="string" required>
      Object hash for verification
    </ParamField>
  </Expandable>
</ParamField>

<ResponseField name="data" type="object">
  <Expandable title="PostResultResponse">
    <ResponseField name="isPb" type="boolean">
      Whether this result is a personal best
    </ResponseField>

    <ResponseField name="insertedId" type="string">
      Database ID of inserted result
    </ResponseField>

    <ResponseField name="xp" type="number">
      XP gained from this result
    </ResponseField>

    <ResponseField name="xpBreakdown" type="object">
      Detailed XP calculation breakdown
    </ResponseField>

    <ResponseField name="dailyXpBonus" type="boolean">
      Whether daily XP bonus was applied
    </ResponseField>

    <ResponseField name="streak" type="number">
      Current streak length
    </ResponseField>

    <ResponseField name="dailyLeaderboardRank" type="number">
      Rank on daily leaderboard (if applicable)
    </ResponseField>
  </Expandable>
</ResponseField>

<Note>
  Results undergo anticheat validation. Invalid results (hash mismatch, suspicious timing, bot detection) will be rejected.
</Note>

### Get Results

Retrieve paginated test results.

```bash theme={null}
curl "https://api.monkeytype.com/results?limit=50&offset=0" \
  -H "Authorization: Bearer YOUR_TOKEN"
```

<ParamField query="limit" type="number" default="50">
  Number of results to return (max 1000)
</ParamField>

<ParamField query="offset" type="number" default="0">
  Offset for pagination
</ParamField>

<ParamField query="onOrAfterTimestamp" type="number">
  Filter results on or after this timestamp
</ParamField>

<Note>
  Premium users can retrieve more results than regular users. Limits are configurable per deployment.
</Note>

### Get Result by ID

Retrieve a specific result by its ID.

```bash theme={null}
curl https://api.monkeytype.com/results/id/{resultId} \
  -H "Authorization: Bearer YOUR_TOKEN"
```

### Delete All Results

Permanently delete all test results.

```bash theme={null}
curl -X DELETE https://api.monkeytype.com/results \
  -H "Authorization: Bearer YOUR_TOKEN"
```

<Warning>
  Requires fresh token. This action is irreversible.
</Warning>

***

## Leaderboards

### Get All-Time Leaderboard

Retrieve global leaderboard entries.

```bash theme={null}
curl "https://api.monkeytype.com/leaderboards?language=english&mode=time&mode2=60&page=0&pageSize=50"
```

<ParamField query="language" type="string" required>
  Language code (e.g., "english")
</ParamField>

<ParamField query="mode" type="string" required>
  Test mode: "time" or "words"
</ParamField>

<ParamField query="mode2" type="string" required>
  Mode variant: "15", "60" for time; "10", "25", "50", "100" for words
</ParamField>

<ParamField query="page" type="number" default="0">
  Page number (0-indexed)
</ParamField>

<ParamField query="pageSize" type="number" default="50">
  Results per page (10-200)
</ParamField>

<ParamField query="friendsOnly" type="boolean" default="false">
  Show only friends (requires authentication)
</ParamField>

<ResponseField name="data" type="object">
  <Expandable title="Leaderboard response">
    <ResponseField name="entries" type="array">
      Array of leaderboard entries
    </ResponseField>

    <ResponseField name="count" type="number">
      Total number of entries
    </ResponseField>

    <ResponseField name="pageSize" type="number">
      Entries per page
    </ResponseField>
  </Expandable>
</ResponseField>

### Get Leaderboard Rank

Get current user's rank on leaderboard.

```bash theme={null}
curl "https://api.monkeytype.com/leaderboards/rank?language=english&mode=time&mode2=60" \
  -H "Authorization: Bearer YOUR_TOKEN"
```

### Get Daily Leaderboard

Retrieve today's daily leaderboard.

```bash theme={null}
curl "https://api.monkeytype.com/leaderboards/daily?language=english&mode=time&mode2=60"
```

<ParamField query="daysBefore" type="number" default="0">
  Get leaderboard from N days ago (0 = today, 1 = yesterday)
</ParamField>

### Get Weekly XP Leaderboard

Retrieve weekly XP leaderboard.

```bash theme={null}
curl "https://api.monkeytype.com/leaderboards/xp/weekly?page=0&pageSize=50"
```

***

## Configs

### Get User Configuration

Retrieve user's configuration settings.

```bash theme={null}
curl https://api.monkeytype.com/configs \
  -H "Authorization: Bearer YOUR_TOKEN"
```

<ResponseField name="data" type="object">
  User's configuration object including theme, test settings, behavior preferences, etc.
</ResponseField>

### Update Configuration

Update user configuration (partial update).

```bash theme={null}
curl -X PATCH https://api.monkeytype.com/configs \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "theme": "serika_dark",
    "difficulty": "expert",
    "showAverage": "wpm"
  }'
```

<Note>
  Only provided fields are updated. Missing fields remain unchanged.
</Note>

***

## Quotes

### Get Quote Submissions

Retrieve pending quote submissions (moderators only).

```bash theme={null}
curl https://api.monkeytype.com/quotes \
  -H "Authorization: Bearer YOUR_TOKEN"
```

<Warning>
  Requires `quoteMod` permission.
</Warning>

### Submit Quote

Submit a new quote for approval.

```bash theme={null}
curl -X POST https://api.monkeytype.com/quotes \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "text": "Quote text that is at least 60 characters long to meet requirements",
    "source": "Author Name",
    "language": "english",
    "captcha": "CAPTCHA_TOKEN"
  }'
```

<ParamField body="text" type="string" required>
  Quote text (minimum 60 characters)
</ParamField>

<ParamField body="source" type="string" required>
  Quote author or source
</ParamField>

<ParamField body="language" type="string" required>
  Language code
</ParamField>

<ParamField body="captcha" type="string" required>
  reCAPTCHA token
</ParamField>

### Report Quote

Report a problematic quote.

```bash theme={null}
curl -X POST https://api.monkeytype.com/quotes/report \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "quoteId": "123",
    "quoteLanguage": "english",
    "reason": "inappropriate",
    "comment": "Optional comment",
    "captcha": "CAPTCHA_TOKEN"
  }'
```

***

## Presets

### Get Presets

Retrieve user's test presets.

```bash theme={null}
curl https://api.monkeytype.com/presets \
  -H "Authorization: Bearer YOUR_TOKEN"
```

### Create Preset

Create a new test preset.

```bash theme={null}
curl -X POST https://api.monkeytype.com/presets \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "My Preset",
    "config": {
      "mode": "time",
      "time": 60,
      "language": "english",
      "difficulty": "normal"
    }
  }'
```

### Update Preset

Update an existing preset.

```bash theme={null}
curl -X PATCH https://api.monkeytype.com/presets \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "_id": "507f1f77bcf86cd799439011",
    "name": "Updated Name",
    "config": {}
  }'
```

### Delete Preset

Delete a preset by ID.

```bash theme={null}
curl -X DELETE https://api.monkeytype.com/presets/{presetId} \
  -H "Authorization: Bearer YOUR_TOKEN"
```

***

## ApeKeys

### List ApeKeys

Retrieve all API keys for the current user.

```bash theme={null}
curl https://api.monkeytype.com/ape-keys \
  -H "Authorization: Bearer YOUR_TOKEN"
```

### Generate ApeKey

Create a new API key.

```bash theme={null}
curl -X POST https://api.monkeytype.com/ape-keys \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "My Integration",
    "enabled": true
  }'
```

### Update ApeKey

Modify an existing API key.

```bash theme={null}
curl -X PATCH https://api.monkeytype.com/ape-keys/{apeKeyId} \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name": "Updated Name", "enabled": false}'
```

### Delete ApeKey

Delete an API key.

```bash theme={null}
curl -X DELETE https://api.monkeytype.com/ape-keys/{apeKeyId} \
  -H "Authorization: Bearer YOUR_TOKEN"
```

***

## Tags

### Get Tags

Retrieve all tags for the current user.

```bash theme={null}
curl https://api.monkeytype.com/users/tags \
  -H "Authorization: Bearer YOUR_TOKEN"
```

<ResponseField name="data" type="array">
  Array of tag objects with ID, name, and personal bests
</ResponseField>

### Create Tag

Create a new tag.

```bash theme={null}
curl -X POST https://api.monkeytype.com/users/tags \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"tagName": "Practice"}'
```

<ParamField body="tagName" type="string" required>
  Tag name (1-16 characters)
</ParamField>

<ResponseField name="data" type="object">
  Created tag object with \_id and name
</ResponseField>

### Update Tag

Update an existing tag's name.

```bash theme={null}
curl -X PATCH https://api.monkeytype.com/users/tags \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "tagId": "507f1f77bcf86cd799439011",
    "newName": "Updated Name"
  }'
```

<ParamField body="tagId" type="string" required>
  Tag ID to update
</ParamField>

<ParamField body="newName" type="string" required>
  New tag name (1-16 characters)
</ParamField>

### Delete Tag

Delete a tag by ID.

```bash theme={null}
curl -X DELETE https://api.monkeytype.com/users/tags/{tagId} \
  -H "Authorization: Bearer YOUR_TOKEN"
```

<ParamField path="tagId" type="string" required>
  Tag ID to delete
</ParamField>

### Delete Tag Personal Best

Clear personal bests for a specific tag.

```bash theme={null}
curl -X DELETE https://api.monkeytype.com/users/tags/{tagId}/personalBest \
  -H "Authorization: Bearer YOUR_TOKEN"
```

<ParamField path="tagId" type="string" required>
  Tag ID to clear personal bests for
</ParamField>

***

## Custom Themes

### Get Custom Themes

Retrieve all custom themes for the current user.

```bash theme={null}
curl https://api.monkeytype.com/users/customThemes \
  -H "Authorization: Bearer YOUR_TOKEN"
```

<ResponseField name="data" type="array">
  Array of custom theme objects with colors
</ResponseField>

### Create Custom Theme

Create a new custom theme.

```bash theme={null}
curl -X POST https://api.monkeytype.com/users/customThemes \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "My Theme",
    "colors": {
      "bg": "#323437",
      "main": "#e2b714",
      "caret": "#e2b714",
      "sub": "#646669",
      "text": "#d1d0c5",
      "error": "#ca4754",
      "errorExtra": "#7e2a33",
      "colorfulError": "#ca4754",
      "colorfulErrorExtra": "#7e2a33"
    }
  }'
```

<ParamField body="name" type="string" required>
  Theme name (1-16 characters)
</ParamField>

<ParamField body="colors" type="object" required>
  <Expandable title="Theme colors">
    <ParamField body="bg" type="string" required>
      Background color (hex)
    </ParamField>

    <ParamField body="main" type="string" required>
      Main color (hex)
    </ParamField>

    <ParamField body="caret" type="string" required>
      Caret color (hex)
    </ParamField>

    <ParamField body="sub" type="string" required>
      Sub color (hex)
    </ParamField>

    <ParamField body="text" type="string" required>
      Text color (hex)
    </ParamField>

    <ParamField body="error" type="string" required>
      Error color (hex)
    </ParamField>

    <ParamField body="errorExtra" type="string" required>
      Error extra color (hex)
    </ParamField>

    <ParamField body="colorfulError" type="string" required>
      Colorful error color (hex)
    </ParamField>

    <ParamField body="colorfulErrorExtra" type="string" required>
      Colorful error extra color (hex)
    </ParamField>
  </Expandable>
</ParamField>

<ResponseField name="data" type="object">
  Created theme with \_id and name
</ResponseField>

### Update Custom Theme

Update an existing custom theme.

```bash theme={null}
curl -X PATCH https://api.monkeytype.com/users/customThemes \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "themeId": "507f1f77bcf86cd799439011",
    "theme": {
      "name": "Updated Theme",
      "colors": {...}
    }
  }'
```

<ParamField body="themeId" type="string" required>
  Theme ID to update
</ParamField>

<ParamField body="theme" type="object" required>
  Theme object with name and colors
</ParamField>

### Delete Custom Theme

Delete a custom theme.

```bash theme={null}
curl -X DELETE https://api.monkeytype.com/users/customThemes \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"themeId": "507f1f77bcf86cd799439011"}'
```

<ParamField body="themeId" type="string" required>
  Theme ID to delete
</ParamField>

***

## Inbox

### Get Inbox

Retrieve user's inbox messages.

```bash theme={null}
curl https://api.monkeytype.com/users/inbox \
  -H "Authorization: Bearer YOUR_TOKEN"
```

<ResponseField name="data" type="object">
  <Expandable title="Inbox data">
    <ResponseField name="inbox" type="array">
      Array of mail objects
    </ResponseField>

    <ResponseField name="maxMail" type="number">
      Maximum number of messages allowed
    </ResponseField>
  </Expandable>
</ResponseField>

### Update Inbox

Mark messages as read or delete them.

```bash theme={null}
curl -X PATCH https://api.monkeytype.com/users/inbox \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "mailIdsToMarkRead": ["uuid1", "uuid2"],
    "mailIdsToDelete": ["uuid3"]
  }'
```

<ParamField body="mailIdsToMarkRead" type="array">
  Array of message UUIDs to mark as read
</ParamField>

<ParamField body="mailIdsToDelete" type="array">
  Array of message UUIDs to delete
</ParamField>

***

## Streak

### Get Streak

Retrieve user's streak data.

```bash theme={null}
curl https://api.monkeytype.com/users/streak \
  -H "Authorization: Bearer YOUR_TOKEN"
```

<ResponseField name="data" type="object">
  <Expandable title="Streak data">
    <ResponseField name="length" type="number">
      Current streak length in days
    </ResponseField>

    <ResponseField name="maxLength" type="number">
      Maximum streak length achieved
    </ResponseField>

    <ResponseField name="lastResultTimestamp" type="number">
      Timestamp of last result
    </ResponseField>

    <ResponseField name="hourOffset" type="number">
      Hour offset for streak calculation
    </ResponseField>
  </Expandable>
</ResponseField>

### Set Streak Hour Offset

Set the hour offset for streak calculation (can only be set once).

```bash theme={null}
curl -X PATCH https://api.monkeytype.com/users/streak/hourOffset \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"hourOffset": -5}'
```

<ParamField body="hourOffset" type="number" required>
  Hour offset (-11 to 12)
</ParamField>

<Warning>
  This can only be set once and cannot be changed.
</Warning>

***

## Connections

### Get Connections

Retrieve user's connections (friends).

```bash theme={null}
curl "https://api.monkeytype.com/connections?status=accepted&type=outgoing" \
  -H "Authorization: Bearer YOUR_TOKEN"
```

<ParamField query="status" type="string">
  Filter by status: "pending", "accepted", "rejected", "blocked"
</ParamField>

<ParamField query="type" type="string">
  Filter by type: "incoming", "outgoing"
</ParamField>

<ResponseField name="data" type="array">
  Array of connection objects
</ResponseField>

### Create Connection

Send a friend request to another user.

```bash theme={null}
curl -X POST https://api.monkeytype.com/connections \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"receiverName": "username"}'
```

<ParamField body="receiverName" type="string" required>
  Username of the user to connect with
</ParamField>

<ResponseField name="data" type="object">
  Created connection object with status "pending"
</ResponseField>

### Update Connection

Accept, reject, or block a connection request.

```bash theme={null}
curl -X PATCH https://api.monkeytype.com/connections/{id} \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"status": "accepted"}'
```

<ParamField path="id" type="string" required>
  Connection ID
</ParamField>

<ParamField body="status" type="string" required>
  New status: "accepted", "rejected", or "blocked"
</ParamField>

### Delete Connection

Remove a connection.

```bash theme={null}
curl -X DELETE https://api.monkeytype.com/connections/{id} \
  -H "Authorization: Bearer YOUR_TOKEN"
```

<ParamField path="id" type="string" required>
  Connection ID to delete
</ParamField>

***

## Discord Integration

### Get Discord OAuth Link

Get the OAuth link to start Discord integration.

```bash theme={null}
curl https://api.monkeytype.com/users/discord/oauth \
  -H "Authorization: Bearer YOUR_TOKEN"
```

<ResponseField name="data" type="object">
  <ResponseField name="url" type="string">
    Discord OAuth URL to redirect user to
  </ResponseField>
</ResponseField>

### Link Discord Account

Link a Discord account after OAuth callback.

```bash theme={null}
curl -X POST https://api.monkeytype.com/users/discord/link \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "tokenType": "Bearer",
    "accessToken": "DISCORD_ACCESS_TOKEN",
    "state": "STATE_FROM_OAUTH"
  }'
```

<ParamField body="tokenType" type="string" required>
  Token type from Discord OAuth
</ParamField>

<ParamField body="accessToken" type="string" required>
  Access token from Discord OAuth
</ParamField>

<ParamField body="state" type="string" required>
  State parameter from OAuth (20 characters)
</ParamField>

<ResponseField name="data" type="object">
  <ResponseField name="discordId" type="string">
    Linked Discord user ID
  </ResponseField>

  <ResponseField name="discordAvatar" type="string">
    Discord avatar URL
  </ResponseField>
</ResponseField>

### Unlink Discord Account

Unlink the connected Discord account.

```bash theme={null}
curl -X POST https://api.monkeytype.com/users/discord/unlink \
  -H "Authorization: Bearer YOUR_TOKEN"
```

***

## Additional User Endpoints

### Get Test Activity

Retrieve complete test activity data (premium feature).

```bash theme={null}
curl https://api.monkeytype.com/users/testActivity \
  -H "Authorization: Bearer YOUR_TOKEN"
```

<Warning>
  Requires premium subscription.
</Warning>

<ResponseField name="data" type="object">
  Test activity data organized by year and day
</ResponseField>

### Update Profile

Update user's public profile information.

```bash theme={null}
curl -X PATCH https://api.monkeytype.com/users/profile \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "bio": "Typing enthusiast",
    "keyboard": "Custom 60%",
    "selectedBadgeId": 1,
    "socialProfiles": {
      "twitter": "username",
      "github": "username"
    },
    "showActivityOnPublicProfile": true
  }'
```

<ParamField body="bio" type="string">
  User biography
</ParamField>

<ParamField body="keyboard" type="string">
  Keyboard information
</ParamField>

<ParamField body="selectedBadgeId" type="number">
  ID of badge to display on profile
</ParamField>

<ParamField body="socialProfiles" type="object">
  Social media profile usernames
</ParamField>

<ParamField body="showActivityOnPublicProfile" type="boolean">
  Whether to show test activity on public profile
</ParamField>

### Get Favorite Quotes

Retrieve user's favorite quotes.

```bash theme={null}
curl https://api.monkeytype.com/users/favoriteQuotes \
  -H "Authorization: Bearer YOUR_TOKEN"
```

<ResponseField name="data" type="object">
  Favorite quotes organized by language
</ResponseField>

### Add Favorite Quote

Add a quote to favorites.

```bash theme={null}
curl -X POST https://api.monkeytype.com/users/favoriteQuotes \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "language": "english",
    "quoteId": "123"
  }'
```

<ParamField body="language" type="string" required>
  Language code
</ParamField>

<ParamField body="quoteId" type="string" required>
  Quote ID to add to favorites
</ParamField>

### Remove Favorite Quote

Remove a quote from favorites.

```bash theme={null}
curl -X DELETE https://api.monkeytype.com/users/favoriteQuotes \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "language": "english",
    "quoteId": "123"
  }'
```

<ParamField body="language" type="string" required>
  Language code
</ParamField>

<ParamField body="quoteId" type="string" required>
  Quote ID to remove from favorites
</ParamField>

***

## Error Responses

All endpoints may return these common error responses:

<ResponseExample>
  ```json 400 Bad Request theme={null}
  {
    "message": "Invalid request parameters"
  }
  ```

  ```json 401 Unauthorized theme={null}
  {
    "message": "Unauthorized"
  }
  ```

  ```json 422 Validation Error theme={null}
  {
    "message": "Invalid request data schema",
    "validationErrors": [
      "wpm must be a positive number",
      "mode is required"
    ]
  }
  ```

  ```json 429 Rate Limited theme={null}
  {
    "message": "Request limit reached, please try again later."
  }
  ```

  ```json 460 Test Too Short theme={null}
  {
    "message": "Test is too short"
  }
  ```
</ResponseExample>

## Rate Limits

Endpoints have varying rate limits. Common limits:

* **User endpoints**: 30-60 requests per minute
* **Result submission**: 500 per day
* **Leaderboards**: 60 per minute
* **Config updates**: 120 per hour

See [Authentication](/api/authentication) for rate limit details.
