Creating the User JWT
Before the SDK can show nutrition or training features, it needs to know who the user is. You tell it by passing a JWT (JSON Web Token) into the connect call. Your backend creates this token β the SDK never sees your user's password.
Three credentials, three purposesβ
| Credential | Who creates it | Where you use it |
|---|---|---|
| SDK API Key | Azeoo team (see Getting your API Key) | initialize(apiKey) β identifies your app |
| SDK Secret Key | Azeoo team (provided alongside the API key) | Your backend β signs the User JWT |
| User JWT | Your backend (see below) | connect(token, ...) β identifies the logged-in user |
The SDK credential platform is coming soon. In the meantime, contact the Azeoo team to receive your SDK API Key and Secret Key.
The big pictureβ
Steps 5-6 happen once at app launch. Steps 1-4 and 7-10 happen each time a user logs in.
Step-by-step: creating the JWT on your serverβ
1. Collect the user's profile after loginβ
When a user logs in to your app, you already have their profile. Pick the five fields the SDK needs:
| Claim | Type | Required | Description | Example |
|---|---|---|---|---|
id | string | Yes | Your unique identifier for this user | "user-42" |
email | string | Yes | User's email address | "john@example.com" |
first_name | string | Yes | User's first name | "John" |
last_name | string | Yes | User's last name | "Doe" |
birthday | string | Yes | Date of birth, format YYYY-MM-DD | "1990-05-15" |
2. Sign the JWT with HS256β
Use the SDK Secret Key (provided by the Azeoo team) to sign the token.
- Algorithm:
HS256(HMAC-SHA256) - Standard claims: always include
iat(issued at) andexp(expiration) - Recommended expiration: 5 minutes (
exp = iat + 300). The token only needs to live long enough for the mobile app to callconnect.
The resulting JWT payload looks like this:
{
"id": "user-42",
"email": "john@example.com",
"first_name": "John",
"last_name": "Doe",
"birthday": "1990-05-15",
"iat": 1779451212,
"exp": 1779451512
}
3. Return the JWT to your mobile appβ
Create an endpoint on your backend (e.g. POST /auth/azeoo-token) that your mobile app calls after login. The response should contain the signed JWT string.
Backend code examplesβ
Node.jsβ
npm install jsonwebtoken
const jwt = require('jsonwebtoken');
// The secret key provided by the Azeoo team
const AZEOO_SECRET_KEY = process.env.AZEOO_SECRET_KEY;
// Call this after the user logs in to YOUR app
function createAzeooToken(user) {
const payload = {
id: user.id, // your user's unique ID (string)
email: user.email,
first_name: user.firstName,
last_name: user.lastName,
birthday: user.birthday, // "YYYY-MM-DD"
};
return jwt.sign(payload, AZEOO_SECRET_KEY, {
algorithm: 'HS256',
expiresIn: 300, // 5 minutes
});
}
// Example Express endpoint
app.post('/auth/azeoo-token', authenticateUser, (req, res) => {
const token = createAzeooToken(req.user);
res.json({ token });
});
Pythonβ
pip install PyJWT
import jwt
import time
import os
AZEOO_SECRET_KEY = os.environ["AZEOO_SECRET_KEY"]
def create_azeoo_token(user):
"""Call this after the user logs in to YOUR app."""
now = int(time.time())
payload = {
"id": user.id, # your user's unique ID (string)
"email": user.email,
"first_name": user.first_name,
"last_name": user.last_name,
"birthday": user.birthday, # "YYYY-MM-DD"
"iat": now,
"exp": now + 300, # 5 minutes
}
return jwt.encode(payload, AZEOO_SECRET_KEY, algorithm="HS256")
# Example Flask endpoint
@app.route("/auth/azeoo-token", methods=["POST"])
@login_required
def azeoo_token():
token = create_azeoo_token(current_user)
return {"token": token}
PHPβ
composer require firebase/php-jwt
use Firebase\JWT\JWT;
// The secret key provided by the Azeoo team
$azeooSecretKey = env('AZEOO_SECRET_KEY');
/**
* Call this after the user logs in to YOUR app.
*/
function createAzeooToken($user): string
{
$now = time();
$payload = [
'id' => (string) $user->id, // your user's unique ID
'email' => $user->email,
'first_name' => $user->first_name,
'last_name' => $user->last_name,
'birthday' => $user->birthday, // "YYYY-MM-DD"
'iat' => $now,
'exp' => $now + 300, // 5 minutes
];
return JWT::encode($payload, $azeooSecretKey, 'HS256');
}
// Example Laravel route
Route::post('/auth/azeoo-token', function (Request $request) {
$token = createAzeooToken($request->user());
return response()->json(['token' => $token]);
})->middleware('auth');
Passing the JWT to the SDKβ
Once your mobile app receives the JWT from your backend, pass it to connect:
Flutterβ
// 1. Get JWT from YOUR backend (not the Azeoo admin endpoint)
final response = await http.post(
Uri.parse('https://your-api.com/auth/azeoo-token'),
headers: {'Authorization': 'Bearer ${yourAuthToken}'},
);
final userJwt = jsonDecode(response.body)['token'];
// 2. Connect the user to the SDK
await AzeooSDK.connect(
token: userJwt,
gender: 'male',
height: Height.scalar(180, HeightUnit.centimeters),
weight: Weight.scalar(75, WeightUnit.kilograms),
);
Android (Kotlin)β
// 1. Get JWT from YOUR backend
val userJwt = yourApi.getAzeooToken(userId)
// 2. Connect the user to the SDK
AzeooSDK.shared.connectUser(
token = userJwt,
gender = "male",
height = 180.0, // in cm
weight = 75.0, // in kg
) { profile, error ->
if (error != null) { /* handle */ return@connectUser }
// Connected β show SDK UI
}
iOS (Swift)β
// 1. Get JWT from YOUR backend
let userJwt = try await yourApi.getAzeooToken(userId: userId)
// 2. Connect the user to the SDK
sdk.connectUser(
token: userJwt,
gender: "male",
height: 180.0,
weight: 75.0
) { result in
switch result {
case .success(let profile):
// Connected β show SDK UI
case .failure(let error):
break
}
}
React Native (TypeScript)β
// 1. Get JWT from YOUR backend
const response = await fetch('https://your-api.com/auth/azeoo-token', {
method: 'POST',
headers: { Authorization: `Bearer ${yourAuthToken}` },
});
const { token: userJwt } = await response.json();
// 2. Connect the user to the SDK
await AzeooSDK.connect(userJwt, 'male', 180, 75);
Common mistakesβ
| Mistake | Why it breaks | Fix |
|---|---|---|
| Signing with the wrong secret | Azeoo API rejects the JWT | Use the SDK Secret Key from the Azeoo team, not your own app secret |
Missing exp claim | Token may be rejected or live too long | Always set exp to iat + 300 (5 minutes) |
Sending birthday as a timestamp | Payload mismatch | Use the format YYYY-MM-DD (e.g. "1990-05-15") |
Passing userId as a separate param | SDK does not accept it | The user id goes inside the JWT payload as id, not as a connect parameter |
Next stepsβ
- Authentication flow overview
- Measurements β height and weight units for
connect - Integration checklist