Portal Login (v1)
Method & Path
POST /api/v1/nutrition/portal/:slug/login
Description
Authenticates a nutrition client using their username and password. Returns a JWT token for subsequent API calls.
Authentication
Required: None (public endpoint)
Headers
| Header | Required | Description |
|---|---|---|
| Content-Type | Yes | application/json |
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| slug | string | Yes | Specialist's portal slug |
Request Body
{
"username": "ahmed.mohamed",
"password": "mypassword123"
}
Body Fields
| Field | Type | Required | Description |
|---|---|---|---|
| username | string | Yes | Client's username |
| password | string | Yes | Client's password |
Response 200 OK
{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"client": {
"id": "507f1f77bcf86cd799439011",
"name": "أحمد محمد",
"email": "ahmed@example.com"
},
"mustChangePassword": false
}
Response Fields
| Field | Type | Description |
|---|---|---|
| token | string | JWT token for API authentication |
| client | object | Basic client information |
| mustChangePassword | boolean | If true, client must change password before using other endpoints |
Token Claims
The returned JWT token contains:
{
"workspaceId": "507f1f77bcf86cd799439012",
"clientId": "507f1f77bcf86cd799439011",
"role": "nutrition_client",
"type": "nutrition_portal_access"
}
Common Errors
- 401 Unauthorized: Invalid username or password
- 403 Forbidden: Account is disabled
- 404 Not Found: Portal not found (invalid slug)
Usage Example
const response = await fetch('/api/v1/nutrition/portal/dr-ahmed/login', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
username: 'ahmed.mohamed',
password: 'mypassword123'
})
});
const { token, client, mustChangePassword } = await response.json();
// Store token for subsequent requests
localStorage.setItem('portal_token', token);