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

# Get Basic User Information

> API reference for fetching basic profile information of the authenticated user (/api/user).

# Get Basic User Information

This endpoint retrieves basic profile information for the user associated with the provided access token.

<Warning>
  **WhatsApp Registration & Null Emails**\
  Users who register via WhatsApp may not have an email address associated with their account initially. In such cases, the `email` field will be `null`.

  **Best Practice for Developers**:

  1. Always check if the `email` field is `null` before using it.
  2. Use `id` or `mubarokah_id` (available in User Details) as the primary identifier in your database.
  3. Provide a fallback mechanism or prompt the user to complete their profile if an email is required by your application.
</Warning>

## Authorization Headers

<ParamField header="Authorization" type="string" required={true}>
  The Bearer token for authentication. Example: `Bearer {YOUR_ACCESS_TOKEN}`
</ParamField>

<ParamField header="Accept" type="string" default="application/json">
  Specifies the desired response format.
</ParamField>

## Required Scope

* `view-user`

Your application must request the `view-user` scope during the OAuth authorization flow to access this endpoint. If the access token does not have this scope, a `403 Forbidden` error will be returned.

## Request Examples

### JavaScript/Node.js

```javascript theme={null}
const getUserInfo = async (accessToken) => {
  try {
    const response = await fetch('https://accounts.mubarokah.com/api/user', {
      method: 'GET',
      headers: {
        'Authorization': `Bearer ${accessToken}`,
        'Accept': 'application/json'
      }
    });
    
    if (!response.ok) {
      const error = await response.json();
      throw new Error(`HTTP ${response.status}: ${error.message || response.statusText}`);
    }
    
    return await response.json();
  } catch (error) {
    console.error('Failed to fetch user info:', error);
    throw error;
  }
};

// Usage example
const accessToken = 'your_access_token_here';
getUserInfo(accessToken)
  .then(user => {
    console.log('User info:', user);
    console.log(`Welcome, ${user.name}!`);
  })
  .catch(error => {
    console.error('Error:', error.message);
  });
```

### Python

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

def get_user_info(access_token):
    """Fetch basic user information from Mubarokah ID API."""
    url = 'https://accounts.mubarokah.com/api/user'
    headers = {
        'Authorization': f'Bearer {access_token}',
        'Accept': 'application/json'
    }
    
    try:
        response = requests.get(url, headers=headers)
        response.raise_for_status()  # Raises an HTTPError for bad responses
        return response.json()
    except requests.exceptions.HTTPError as e:
        if response.status_code == 401:
            raise Exception("Token expired or invalid")
        elif response.status_code == 403:
            raise Exception("Insufficient scope: view-user required")
        else:
            raise Exception(f"HTTP {response.status_code}: {response.text}")
    except requests.exceptions.RequestException as e:
        raise Exception(f"Request failed: {str(e)}")

# Usage example
access_token = "your_access_token_here"
try:
    user_info = get_user_info(access_token)
    print(f"Welcome, {user_info['name']}!")
    print(f"Email: {user_info['email']}")
except Exception as error:
    print(f"Error: {error}")
```

### PHP

```php theme={null}
<?php

function getUserInfo($accessToken) {
    $url = 'https://accounts.mubarokah.com/api/user';
    
    $options = [
        'http' => [
            'header' => [
                "Authorization: Bearer $accessToken",
                "Accept: application/json"
            ],
            'method' => 'GET'
        ]
    ];
    
    $context = stream_context_create($options);
    $result = file_get_contents($url, false, $context);
    
    if ($result === FALSE) {
        throw new Exception('Failed to fetch user information');
    }
    
    $httpCode = intval(substr($http_response_header[0], 9, 3));
    
    if ($httpCode === 401) {
        throw new Exception('Token expired or invalid');
    } elseif ($httpCode === 403) {
        throw new Exception('Insufficient scope: view-user required');
    } elseif ($httpCode !== 200) {
        throw new Exception("HTTP $httpCode: Request failed");
    }
    
    return json_decode($result, true);
}

// Usage example
$accessToken = 'your_access_token_here';
try {
    $userInfo = getUserInfo($accessToken);
    echo "Welcome, {$userInfo['name']}!\n";
    echo "Email: {$userInfo['email']}\n";
} catch (Exception $e) {
    echo "Error: " . $e->getMessage() . "\n";
}
?>
```

### cURL

```bash theme={null}
# Basic request
curl -X GET "https://accounts.mubarokah.com/api/user" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Accept: application/json"

# With error handling and formatting
curl -X GET "https://accounts.mubarokah.com/api/user" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Accept: application/json" \
  -w "HTTP Status: %{http_code}\n" \
  -s | jq '.'
```

## Successful Response (200 OK)

A successful request returns a JSON object containing the user's basic profile information.

**Response Fields:**

<ResponseField name="id" type="number" required={true}>
  The unique identifier for the user.
</ResponseField>

<ResponseField name="name" type="string" required={true}>
  The full name of the user.
</ResponseField>

<ResponseField name="email" type="string">
  The primary email address of the user. **Note**: This field may be `null` if the user registered via WhatsApp and has not yet linked an email address.
</ResponseField>

<ResponseField name="profile_picture" type="string">
  URL to the user's profile picture. May be `null`.
</ResponseField>

<ResponseField name="username" type="string">
  The user's chosen username. Defaults to a unique string or `null` if not set.
</ResponseField>

<ResponseField name="gender" type="string">
  The gender of the user (e.g., "male", "female", "other"). May be `null`.
</ResponseField>

## Example Successful Response

```json theme={null}
{
  "id": 12345,
  "name": "Ahmad Mubarak",
  "email": "ahmad.mubarak@example.com",
  "profile_picture": "https://accounts.mubarokah.com/storage/avatars/12345.jpg",
  "username": "ahmadmubarak",
  "gender": "male"
}
```

## Error Responses

### Common Error Responses

<Tabs>
  <Tab title="401 Unauthorized">
    **Cause**: Access token is missing, invalid, or expired.

    ```json theme={null}
    {
      "message": "Unauthenticated."
    }
    ```

    **Or for expired tokens:**

    ```json theme={null}
    {
        "error": "token_expired",
        "error_description": "The access token provided has expired.",
        "message": "The access token provided has expired."
    }
    ```

    **Resolution**: Refresh the access token or re-authenticate the user.
  </Tab>

  <Tab title="403 Forbidden">
    **Cause**: Access token is valid but lacks the required `view-user` scope.

    ```json theme={null}
    {
      "error": "insufficient_scope",
      "error_description": "The request requires higher privileges than provided by the access token.",
      "message": "Invalid scope(s) provided."
    }
    ```

    **Resolution**: Ensure your application requests the `view-user` scope during OAuth authorization.
  </Tab>

  <Tab title="429 Too Many Requests">
    **Cause**: Rate limit exceeded for API requests.

    ```json theme={null}
    {
      "error": "rate_limit_exceeded",
      "message": "Too many requests. Please try again later.",
      "retry_after": 60
    }
    ```

    **Resolution**: Implement rate limiting in your application and respect the `retry_after` value.
  </Tab>
</Tabs>

## Rate Limiting

This endpoint is subject to rate limiting:

* **Limit**: 100 requests per minute per access token
* **Reset**: Rate limit resets every minute
* **Headers**: Check `X-RateLimit-Remaining` and `X-RateLimit-Reset` response headers

## Testing the Endpoint

### Using the API Playground

You can test this endpoint directly using the API playground above. Make sure you have:

1. A valid access token with `view-user` scope
2. The token is not expired
3. Your application is properly registered

### Integration Testing Script

```javascript theme={null}
// Complete integration test
const testUserInfoEndpoint = async () => {
  const testCases = [
    {
      name: 'Valid token with view-user scope',
      token: 'valid_token_here',
      expectedStatus: 200
    },
    {
      name: 'Expired token',
      token: 'expired_token_here',
      expectedStatus: 401
    },
    {
      name: 'Token without view-user scope',
      token: 'limited_scope_token_here',
      expectedStatus: 403
    }
  ];
  
  for (const testCase of testCases) {
    try {
      console.log(`Testing: ${testCase.name}`);
      const result = await getUserInfo(testCase.token);
      
      if (testCase.expectedStatus === 200) {
        console.log('✅ Success:', result);
        console.log(`User: ${result.name} (${result.email})`);
      }
    } catch (error) {
      console.log(`❌ Expected error for ${testCase.name}:`, error.message);
    }
  }
};

// Run tests
testUserInfoEndpoint();
```

Refer to the general [Error Codes section](../error-codes) for more details on other possible errors.

```
```
