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:
- Obtaining a nonce (a one-time token) to ensure request uniqueness.
- 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:
- Prepare the following parameters:
action
:getnonce
.client_id
: Your unique client identifier.timestamp
: A UNIX timestamp of the current time.
-
Concatenate the parameter values in the following order:
action
,client_id
, andtimestamp
, separating them with commas (,
). -
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). -
Send the request to the
getnonce
API endpoint, appending the generated hash as thesignature
.
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:
- 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.
-
Concatenate the sorted values (alphabetically by key name) of these parameters, separated by commas.
-
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.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
<?php
// Constants
define('API_ENDPOINT', 'https://wbsapi.withings.net');
define('OAUTH2_GRANT_TYPE_AUTHORIZATION_CODE', 'authorization_code');
define('REDIRECT_URI', 'localhost:3000');
define('CLIENT_ID', 'yourclientid');
define('CLIENT_SECRET', 'yourclientsecret');
// Function to generate the HMAC signature
function sign($params, $client_secret) {
$params_to_sign = [
'action' => $params['action'],
'client_id' => $params['client_id']
];
if (!empty($params['timestamp'])) {
$params_to_sign['timestamp'] = $params['timestamp'];
}
if (!empty($params['nonce'])) {
$params_to_sign['nonce'] = $params['nonce'];
}
// Sort and join values by a comma
$sorted_values = implode(',', array_values($params_to_sign));
// Create the HMAC signature using SHA256
return hash_hmac('sha256', $sorted_values, $client_secret);
}
// Function to get the nonce from the API
function getNonce($timestamp) {
$params = [
'action' => 'getnonce',
'client_id' => CLIENT_ID,
'timestamp' => $timestamp
];
$params['signature'] = sign($params, CLIENT_SECRET); // Add signature
$ch = curl_init(API_ENDPOINT . '/v2/signature');
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($params));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
// Execute the request and decode the JSON response
$response = curl_exec($ch);
curl_close($ch);
$data = json_decode($response, true);
return $data['body']['nonce'];
}
// Main function to get and display the nonce
function main() {
$now = time(); // Current timestamp in Unix form
$nonce = getNonce($now);
echo $nonce . "\n";
}
// Run the main function
main();