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

# Users

> Access user profiles and manage accounts

## Overview

The Users endpoints provide access to public user profiles, allow users to manage their own accounts, and enable bot management. User profiles include forecasting statistics, bio information, and social links.

***

## Get Current User

<CodeGroup>
  ```bash cURL theme={null}
  curl -X GET "https://www.metaculus.com/api/users/me/" \
    -H "Authorization: Token YOUR_TOKEN"
  ```

  ```python Python theme={null}
  import requests

  response = requests.get(
      "https://www.metaculus.com/api/users/me/",
      headers={"Authorization": "Token YOUR_TOKEN"}
  )
  print(response.json())
  ```
</CodeGroup>

`GET /api/users/me/`

Retrieve the authenticated user's complete profile, including private information.

### Response

<ResponseField name="id" type="integer">
  User ID
</ResponseField>

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

<ResponseField name="email" type="string">
  Email address (private)
</ResponseField>

<ResponseField name="date_joined" type="string (datetime)">
  When the user registered
</ResponseField>

<ResponseField name="bio" type="string">
  User bio in markdown
</ResponseField>

<ResponseField name="website" type="string">
  Personal website URL
</ResponseField>

<ResponseField name="is_bot" type="boolean">
  Whether this is a bot account
</ResponseField>

<ResponseField name="is_staff" type="boolean">
  Whether the user is Metaculus staff
</ResponseField>

<ResponseField name="is_superuser" type="boolean">
  Whether the user has admin privileges
</ResponseField>

<ResponseField name="profile_picture" type="string">
  Profile picture URL
</ResponseField>

<ResponseField name="location" type="string">
  Geographic location
</ResponseField>

<ResponseField name="occupation" type="string">
  Professional occupation
</ResponseField>

<ResponseField name="twitter" type="string">
  Twitter handle
</ResponseField>

<ResponseField name="linkedin" type="string">
  LinkedIn profile URL
</ResponseField>

<ResponseField name="github" type="string">
  GitHub username
</ResponseField>

<ResponseField name="hide_community_prediction" type="boolean">
  Whether to hide community predictions by default
</ResponseField>

<ResponseField name="is_onboarding_complete" type="boolean">
  Whether the user has completed onboarding
</ResponseField>

<ResponseField name="prediction_expiration_percent" type="number">
  Default forecast auto-withdrawal percentage
</ResponseField>

<ResponseField name="app_theme" type="string">
  UI theme preference: `light`, `dark`, or `auto`
</ResponseField>

<ResponseField name="language" type="string">
  Preferred language code
</ResponseField>

<ResponseField name="api_access_tier" type="string">
  API access tier level
</ResponseField>

<ResponseField name="unsubscribed_mailing_tags" type="array">
  List of email notification types the user has unsubscribed from
</ResponseField>

<ResponseField name="formerly_known_as" type="array">
  Previous usernames
</ResponseField>

<ResponseField name="metadata" type="object">
  Additional user metadata
</ResponseField>

***

## Get User Profile

<CodeGroup>
  ```bash cURL theme={null}
  curl -X GET "https://www.metaculus.com/api/users/12345/" \
    -H "Authorization: Token YOUR_TOKEN"
  ```

  ```python Python theme={null}
  import requests

  response = requests.get(
      "https://www.metaculus.com/api/users/12345/",
      headers={"Authorization": "Token YOUR_TOKEN"}
  )
  print(response.json())
  ```
</CodeGroup>

`GET /api/users/{userId}/`

Retrieve a public user profile.

### Path Parameters

<ParamField path="userId" type="integer" required>
  The user ID
</ParamField>

### Response

Returns the same fields as `/api/users/me/` but excludes private information:

* Email address
* Unsubscribed mailing tags
* Private metadata fields

***

## List Users

<CodeGroup>
  ```bash cURL theme={null}
  curl -X GET "https://www.metaculus.com/api/users/?limit=20" \
    -H "Authorization: Token YOUR_TOKEN"
  ```

  ```python Python theme={null}
  import requests

  response = requests.get(
      "https://www.metaculus.com/api/users/",
      headers={"Authorization": "Token YOUR_TOKEN"},
      params={"limit": 20}
  )
  print(response.json())
  ```
</CodeGroup>

`GET /api/users/`

Retrieve a paginated list of user profiles.

### Query Parameters

<ParamField query="limit" type="integer" default="20">
  Number of users to return
</ParamField>

<ParamField query="offset" type="integer" default="0">
  Pagination offset
</ParamField>

***

## Update Profile

<CodeGroup>
  ```bash cURL theme={null}
  curl -X PATCH "https://www.metaculus.com/api/users/me/update/" \
    -H "Authorization: Token YOUR_TOKEN" \
    -H "Content-Type: application/json" \
    -d '{
      "bio": "Updated bio",
      "website": "https://example.com",
      "location": "San Francisco, CA"
    }'
  ```

  ```python Python theme={null}
  import requests

  response = requests.patch(
      "https://www.metaculus.com/api/users/me/update/",
      headers={
          "Authorization": "Token YOUR_TOKEN",
          "Content-Type": "application/json"
      },
      json={
          "bio": "Updated bio",
          "website": "https://example.com",
          "location": "San Francisco, CA"
      }
  )
  print(response.json())
  ```
</CodeGroup>

`PATCH /api/users/me/update/`

Update the authenticated user's profile.

### Request Body

All fields are optional. Only include fields you want to update.

<ParamField body="bio" type="string">
  User bio (supports markdown)
</ParamField>

<ParamField body="website" type="string">
  Personal website URL
</ParamField>

<ParamField body="location" type="string">
  Geographic location
</ParamField>

<ParamField body="occupation" type="string">
  Professional occupation
</ParamField>

<ParamField body="twitter" type="string">
  Twitter handle
</ParamField>

<ParamField body="linkedin" type="string">
  LinkedIn profile URL
</ParamField>

<ParamField body="github" type="string">
  GitHub username
</ParamField>

<ParamField body="profile_picture" type="string">
  Profile picture URL
</ParamField>

<ParamField body="hide_community_prediction" type="boolean">
  Hide community predictions by default
</ParamField>

<ParamField body="app_theme" type="string">
  UI theme: `light`, `dark`, or `auto`
</ParamField>

<ParamField body="language" type="string">
  Preferred language code (e.g., "en", "es")
</ParamField>

***

## Change Username

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST "https://www.metaculus.com/api/users/change-username/" \
    -H "Authorization: Token YOUR_TOKEN" \
    -H "Content-Type: application/json" \
    -d '{"username": "new_username"}'
  ```

  ```python Python theme={null}
  import requests

  response = requests.post(
      "https://www.metaculus.com/api/users/change-username/",
      headers={
          "Authorization": "Token YOUR_TOKEN",
          "Content-Type": "application/json"
      },
      json={"username": "new_username"}
  )
  print(response.json())
  ```
</CodeGroup>

`POST /api/users/change-username/`

Change the authenticated user's username.

### Request Body

<ParamField body="username" type="string" required>
  New username. Must be unique and meet format requirements.
</ParamField>

<Note>
  **Username Change Restrictions**

  * Can only change username once every 180 days
  * Username must be 1-30 characters
  * Can only contain letters, numbers, and @/./+/-/\_ characters
  * Cannot be a reserved username (e.g., "admin", "moderator")
</Note>

***

## Change Password

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST "https://www.metaculus.com/api/users/me/password/" \
    -H "Authorization: Token YOUR_TOKEN" \
    -H "Content-Type: application/json" \
    -d '{
      "old_password": "current_password",
      "new_password": "new_secure_password"
    }'
  ```

  ```python Python theme={null}
  import requests

  response = requests.post(
      "https://www.metaculus.com/api/users/me/password/",
      headers={
          "Authorization": "Token YOUR_TOKEN",
          "Content-Type": "application/json"
      },
      json={
          "old_password": "current_password",
          "new_password": "new_secure_password"
      }
  )
  print(response.status_code)
  ```
</CodeGroup>

`POST /api/users/me/password/`

Change the authenticated user's password.

### Request Body

<ParamField body="old_password" type="string" required>
  Current password
</ParamField>

<ParamField body="new_password" type="string" required>
  New password (must meet security requirements)
</ParamField>

***

## Bot Management

### List My Bots

<CodeGroup>
  ```bash cURL theme={null}
  curl -X GET "https://www.metaculus.com/api/users/me/bots/" \
    -H "Authorization: Token YOUR_TOKEN"
  ```

  ```python Python theme={null}
  import requests

  response = requests.get(
      "https://www.metaculus.com/api/users/me/bots/",
      headers={"Authorization": "Token YOUR_TOKEN"}
  )
  print(response.json())
  ```
</CodeGroup>

`GET /api/users/me/bots/`

Retrieve all bots created by the authenticated user.

### Response

<ResponseField name="results" type="array">
  Array of bot user objects
</ResponseField>

***

### Create Bot

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST "https://www.metaculus.com/api/users/me/bots/create/" \
    -H "Authorization: Token YOUR_TOKEN" \
    -H "Content-Type: application/json" \
    -d '{
      "username": "my_bot",
      "bio": "Automated forecasting bot"
    }'
  ```

  ```python Python theme={null}
  import requests

  response = requests.post(
      "https://www.metaculus.com/api/users/me/bots/create/",
      headers={
          "Authorization": "Token YOUR_TOKEN",
          "Content-Type": "application/json"
      },
      json={
          "username": "my_bot",
          "bio": "Automated forecasting bot"
      }
  )
  bot = response.json()
  print(f"Created bot: {bot['username']} (ID: {bot['id']})")
  ```
</CodeGroup>

`POST /api/users/me/bots/create/`

Create a new bot account.

### Request Body

<ParamField body="username" type="string" required>
  Bot username
</ParamField>

<ParamField body="bio" type="string">
  Bot description
</ParamField>

### Response

Returns the created bot user object.

***

### Get Bot Token

<CodeGroup>
  ```bash cURL theme={null}
  curl -X GET "https://www.metaculus.com/api/users/me/bots/12345/token/" \
    -H "Authorization: Token YOUR_TOKEN"
  ```

  ```python Python theme={null}
  import requests

  response = requests.get(
      "https://www.metaculus.com/api/users/me/bots/12345/token/",
      headers={"Authorization": "Token YOUR_TOKEN"}
  )
  token_data = response.json()
  print(f"Bot token: {token_data['token']}")
  ```
</CodeGroup>

`GET /api/users/me/bots/{botId}/token/`

Retrieve or generate an API token for a bot.

### Path Parameters

<ParamField path="botId" type="integer" required>
  The bot's user ID
</ParamField>

### Response

<ResponseField name="token" type="string">
  The bot's API authentication token
</ResponseField>

<Warning>
  **Store Bot Tokens Securely**

  Bot tokens provide full API access. Store them securely and never commit them to version control.
</Warning>

***

### Update Bot Profile

<CodeGroup>
  ```bash cURL theme={null}
  curl -X PATCH "https://www.metaculus.com/api/users/me/bots/12345/update/" \
    -H "Authorization: Token YOUR_TOKEN" \
    -H "Content-Type: application/json" \
    -d '{
      "bio": "Updated bot description",
      "website": "https://github.com/user/bot"
    }'
  ```

  ```python Python theme={null}
  import requests

  response = requests.patch(
      "https://www.metaculus.com/api/users/me/bots/12345/update/",
      headers={
          "Authorization": "Token YOUR_TOKEN",
          "Content-Type": "application/json"
      },
      json={
          "bio": "Updated bot description",
          "website": "https://github.com/user/bot"
      }
  )
  print(response.json())
  ```
</CodeGroup>

`PATCH /api/users/me/bots/{botId}/update/`

Update a bot's profile information.

### Path Parameters

<ParamField path="botId" type="integer" required>
  The bot's user ID
</ParamField>

### Request Body

Same fields as user profile update, plus:

<ParamField body="username" type="string">
  Update bot username (bots can change username without time restrictions)
</ParamField>

***

## Example: Complete Bot Setup

```python theme={null}
import requests

# Step 1: Create a bot
response = requests.post(
    "https://www.metaculus.com/api/users/me/bots/create/",
    headers={"Authorization": "Token YOUR_USER_TOKEN"},
    json={
        "username": "my_forecasting_bot",
        "bio": "Automated forecasting using ML models",
        "website": "https://github.com/user/forecasting-bot"
    }
)
bot = response.json()
bot_id = bot["id"]

# Step 2: Get bot token
response = requests.get(
    f"https://www.metaculus.com/api/users/me/bots/{bot_id}/token/",
    headers={"Authorization": "Token YOUR_USER_TOKEN"}
)
bot_token = response.json()["token"]

print(f"Bot created! Use this token for API calls: {bot_token}")

# Step 3: Use bot token to submit forecasts
response = requests.post(
    "https://www.metaculus.com/api/questions/forecast/",
    headers={"Authorization": f"Token {bot_token}"},
    json=[{"question": 1, "probability_yes": 0.75}]
)

print(f"Forecast submitted: {response.status_code}")
```
