Skip to main content

Activate API

Now that we know how to sign requests, we can proceed with the activation of the device. We're going to use the Activate API for this, it serves the following purposes:

  • Create a Withings user account
  • Link devices specified by their MAC addresses in the request to the created user
  • Activate the cellular device service and enable invoicing

Run In Postman

Notes

  • To activate the Withings HUB cellular service, the MAC address of the Withings HUB must be included in the list of mac_addresses along with other Withings devices.
  • Trying to activate a device that isn't authorized will result in an error.
  • The authorization code returned in this API is valid for 10min.
  • In your application, one email address matches one Withings user. Use a different email address for each member of your program. See Email address already used.

Email address already used

The email decides which Withings user the devices are linked to.

  • No user created by your application has this email: a new Withings user is created and the devices are linked to this user.
  • A user your application created already has this email: no new user is created. The devices are linked to this existing user, and the user's profile is updated with the values you send. The requesttoken call then returns the userid of this existing user.

Only the users created by your application are checked. If the person already has a Withings account with the same email, for example one created in the Withings app, a second Withings user is created, with its own userid. The two users share the same email but not the same devices or data.

So never use the same email address for two different people: their devices and their data would go to the same Withings user.

Once you've activated your device, you can go to the next step to learn how to exchange the code for an access and refresh token.

Parameters

Refer to the API reference or

Toggle me!
ParameterRequiredTypeDescription
actionYesstringThe service action name. Must be set to activate.
client_idYesstringThe ID of your client.
nonceYesstringA random token used to prevent replay attacks. Refer to the Signature v2 - Getnonce.
signatureYesstringA hash of the parameters. See Signature hash protocol for details.
mailingprefYesbooleanIndicates whether the customer has accepted Withings commercial contacts.
birthdateYesintegerThe Unix timestamp of the user's birthdate.
measuresYesjson_stringUser measures (refer to Measures model).
genderYesintegerGender of the user: 0 for male, 1 for female.
preflangYesstringUser's language preference (e.g., en_EN, fr_FR).
unit_prefYesjsonUser's unit preferences (refer to Unit preferences model).
emailYesemailThe user's email address. In your application, one email address matches one Withings user. See Email address already used.
timezoneYestimezoneUser's timezone (e.g., Europe/Paris, America/New_York). A complete list can be found here.
shortnameYesstringA three-character representation of the end user (e.g., ROB for Robert). Must match regex: /^[a-zA-Z0-9]{3}$/.
external_idYesstringA unique identifier used by the partner to identify the end user.
mac_addressesYesmacaddressList of Withings device MAC addresses to be linked to the created user (e.g., ["00:24:e4:xx:xx:xx","00:24:e4:xx:xx:xx"]). See Find a device serial number.
redirect_uriYespartner_redirect_uriThe URI to redirect the user after authorization. This must be set as the Callback URL in your partner application. You can specify multiple URLs separated by commas.
firstnameNostringThe user's first name. Defaults to the value of shortname if not set.
lastnameNostringThe user's last name. Defaults to the value of shortname if not set.
phonenumberNostringPhone number in E.164 format. Used for two-factor authentication verification (recommended).
recovery_codeNostringA recovery code that can be used as a second authentication factor in the Withings app.
goalsNojsonUser goals (refer to Goals model).

Snippet

const axios = require('axios');
const { sign, getNonce } = require('../signature');

// Constants
const API_ENDPOINT = 'https://wbsapi.withings.net';
const OAUTH2_GRANT_TYPE_AUTHORIZATION_CODE = 'authorization_code';
const REDIRECT_URI = 'YOUR_REDIRECT_URI';
const CLIENT_ID = 'YOURCLIENTID';
const CLIENT_SECRET = 'YOURCLIENTSECRET';

const MEASURE_TYPE_HEIGHT = 4;
const MEASURE_TYPE_WEIGHT = 1;
const UNIT_HEIGHT_M  = 6;
const UNIT_HEIGHT_IN = 7;
const UNIT_WEIGHT_KG = 1;
const UNIT_WEIGHT_LB = 2;
const UNIT_WEIGHT_STLB = 14;
const UNIT_DISTANCE_KM = 6;
const UNIT_DISTANCE_YD = 8;
const UNIT_TEMPERATURE_C = 11;
const UNIT_TEMPERATURE_F = 13;


async function activate(nonce, mac_addresses, user) {
  const params = {
    action: 'activate',
    client_id: CLIENT_ID,
    nonce,
    mac_addresses: JSON.stringify(mac_addresses),
    email: user.email,
    shortname: user.shortname,
    gender: user.gender,
    birthdate: user.birthdate,
    measures: JSON.stringify(user.measures),
    external_id: user.external_id,
    mailingpref: user.mailingpref,
    unit_pref: JSON.stringify(user.unit_pref),
    preflang: user.preflang,
    timezone: user.timezone,
  };
  if (user.firstname) {
    params.firstname = user.firstname;
  }
  if (user.lastname) {
    params.lastname = user.lastname;
  }
  if (user.phonenumber) {
    params.phonenumber = user.phonenumber
  }
  if (user.goals) {
    params.goals = user.goals;
  }
  if (user.recovery_code) {
    params.recovery_code = user.recovery_code;
  }
  params.signature = sign(params, CLIENT_SECRET);
  const { data } = await axios.post(API_ENDPOINT + '/v2/user', params);
  return data;
}

async function main() {
  const mac_addresses = ['00:24:e4:78:5c:3e', '00:24:e4:61:5a:3d'];
  const measures  = [
    { value: 190, unit: -2, type: MEASURE_TYPE_HEIGHT }, //1m90
    { value: 90, unit: 0, type:  MEASURE_TYPE_WEIGHT} //90kg
  ];
  const unit_pref = {
    weight: UNIT_WEIGHT_KG,
    height: UNIT_HEIGHT_M,
    distance: UNIT_DISTANCE_KM,
    temperature: UNIT_TEMPERATURE_C
  };
  const mandatory_params_user = {
    mailingpref: 0,
    birthdate: 848166152,
    measures, // measurements should always be passed in kg/m
    gender: 0,
    preflang: 'en_US',
    unit_pref,
    email: 'john.doe@example.com',
    timezone: 'America/New_York',
    shortname: 'HNI',
    external_id: 'my-external-id' //id of this user on your side
  }
  const optional_params_user  = {
    firstname: 'John', //if not set, will take the same value as shortname
    lastname: 'Doe', //if not set, will take the same value as shortname
    phonenumber: '+551155256325', //Phone number in E.164 format.
    recovery_code: 'abcde12345',
    goals: null
  }
  const user = {...mandatory_params_user, ...optional_params_user};
  const now = Math.round((Date.now() / 1000));
  const response = await activate(await getNonce(now, CLIENT_ID), mac_addresses, user);
  console.log(JSON.stringify(response));
}

main();

Response

{
"status": 0,
"body": {
"user": {
"code": "4ab52f3da1e1c8da346ec68ff26a45104c4859f6",
"external_id": "my-external-id"
},
"devices": [
{
"deviceid": "1f5cd788497dc62392793c3e87791f6183ae244a",
"mac_address": "00:24:e4:72:9a:68",
"type": "Activity Tracker",
"battery": "low",
"model": "Activite Steel HR",
"model_id": 55,
"timezone": "Europe/Paris",
"last_session_date": 1569996478
}
]
}
}

Possible Errors

Invalid Signature

{
"status": 503,
"body": {},
"error": "Invalid Params: Invalid HMAC signature"
}

Unauthorized device

{
"status": 277,
"body": {},
"error": "Unauthorized - Mac addresses [00:24:e4:72:9a:68] not allowed for this partner (wrong consumer)"
}

Invalid Parameter

{
"status": 503,
"body": {},
"error": "Invalid Params wrong HEIGHT value : out of range"
}