Skip to main content

Learn how to sign requests

To securely interact with Withings APIs, partners must sign some of their requests using HMAC SHA-256.
This ensures that requests are properly authenticated and tamper-proof.
The signature mechanism requires two distinct steps:

  1. Obtaining a nonce (a one-time token) to ensure request uniqueness.
  2. Signing the actual API request using the nonce and a hash-based signature.

Step 1: Obtaining a Nonce

The first step in signing a request is acquiring a nonce — a cryptographically unique value used to prevent replay attacks.
This is done by invoking the Signature v2 - Getnonce endpoint.
The nonce is a transient token, and every request requires a fresh one. The process is as follows:

  1. Prepare the following parameters:
  • action: getnonce.
  • client_id: Your unique client identifier.
  • timestamp: A UNIX timestamp of the current time.
  1. Concatenate the parameter values in the following order: action, client_id, and timestamp, separating them with commas (,).

  2. Use the HMAC SHA-256 algorithm to hash this concatenated string.
    The secret key for the HMAC function is your client secret (found in your Withings Developer Dashboard).

  3. Send the request to the getnonce API endpoint, appending the generated hash as the signature.

Run In Postman

See the code snippet for a complete implementation example.

Step 2: Signing the Actual API Request

Once you have the nonce, you can proceed to sign the actual API request. Here’s how it works:

  1. Generate the signature using the following parameters:
  • action: The specific API action you are calling.
  • client_id: Your unique client identifier.
  • nonce: The nonce obtained from Step 1.
  1. Concatenate the sorted values (alphabetically by key name) of these parameters, separated by commas.

  2. Compute the HMAC SHA-256 hash using your client secret as the key.

See the code snippet for an implementation example.

Snippets

Here is an example of a function that allows us to sign request and handle the timestamp (to get a nonce), or the nonce parameter to sign requests later on.

const axios  = require('axios');
const crypto = require('crypto');

// Constants
const API_ENDPOINT = 'https://wbsapi.withings.net';
const OAUTH2_GRANT_TYPE_AUTHORIZATION_CODE = 'authorization_code';
const REDIRECT_URI = 'localhost:3000';
const CLIENT_ID = 'yourclientid';
const CLIENT_SECRET = 'yourclientsecret';

function sign(params, client_secret) {
    const params_to_sign = {
        action: params.action,
        client_id: params.client_id
    }
    if (params.timestamp) {
        params_to_sign.timestamp = params.timestamp;
    }
    if (params.nonce) {
        params_to_sign.nonce = params.nonce;
    }
    const sorted_values = Object.values(params_to_sign).join(',');
    const hmac = crypto.createHmac('sha256', client_secret);
    hmac.update(sorted_values);
    return hmac.digest("hex");
}

async function getNonce(timestamp) {
  const params = {
    action: 'getnonce',
    client_id: CLIENT_ID,
    timestamp //timestamp should be in unix form
  };
  params.signature = sign(params, CLIENT_SECRET);
  const { data } = await axios.post(API_ENDPOINT + '/v2/signature', params);
  return data.body.nonce;
}

async function main() {
  const now = Math.round((Date.now() / 1000));
  const nonce = await getNonce(now);
  console.log(nonce);
}

Examples