Skip to content

Computing the HMAC

Several APIs (ZAGIS, and the POST endpoints of PharmaPortal) require an HMAC in a header as an integrity check. The receiver recomputes the same HMAC; if they do not match, the request is rejected with a 401.

The HMAC is always built the same way:

Property Value
Algorithm HMAC with SHA-512
Key The API secret issued to your organisation
Input The exact bytes of the request body you send
Encoding Hexadecimal (lowercase)
Header x-zagis-hmac, x-portal-hmac or x-zagis-offerte-hmac (see the relevant endpoint)

Compute the HMAC over exactly what you send

Serialise your JSON or CSV to a string/bytes once, use that value for both the HMAC and the request body, and send it unchanged. If you re-serialise the body (different whitespace, key order or line endings) the HMAC will differ and you will get a 401.

Examples

The examples below compute the hex HMAC of a request body using your API secret.

import hmac
import hashlib

secret = b"your-api-secret"
body = b'{"zindexNummer": 12345678}'   # exactly the bytes you send

signature = hmac.new(secret, body, hashlib.sha512).hexdigest()
<?php
$secret = 'your-api-secret';
$body   = '{"zindexNummer": 12345678}'; // exactly the bytes you send

$signature = hash_hmac('sha512', $body, $secret); // hex, lowercase
using System.Security.Cryptography;
using System.Text;

var secret = "your-api-secret";
var body   = "{\"zindexNummer\": 12345678}"; // exactly the bytes you send

using var hmac = new HMACSHA512(Encoding.UTF8.GetBytes(secret));
var hash = hmac.ComputeHash(Encoding.UTF8.GetBytes(body));
var signature = Convert.ToHexString(hash).ToLowerInvariant();
const crypto = require("crypto");

const secret = "your-api-secret";
const body = JSON.stringify({ zindexNummer: 12345678 }); // send exactly this string

const signature = crypto
  .createHmac("sha512", secret)
  .update(body, "utf8")
  .digest("hex");
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;

String secret = "your-api-secret";
String body   = "{\"zindexNummer\": 12345678}"; // exactly the bytes you send

Mac mac = Mac.getInstance("HmacSHA512");
mac.init(new SecretKeySpec(secret.getBytes(StandardCharsets.UTF_8), "HmacSHA512"));
byte[] hash = mac.doFinal(body.getBytes(StandardCharsets.UTF_8));

StringBuilder sb = new StringBuilder();
for (byte b : hash) sb.append(String.format("%02x", b));
String signature = sb.toString();

Full request (example)

Compute the HMAC over the same body you send and put it in the correct header:

BODY='{"zindexNummer": 12345678}'
SIG=$(printf '%s' "$BODY" | openssl dgst -sha512 -hmac "your-api-secret" | awk '{print $2}')

curl -X POST https://demo.zagis.nl/api/zagis/prijsCheck \
  -H "x-zagis-key: <your-api-key>" \
  -H "x-zagis-hmac: $SIG" \
  -H "content-type: application/json" \
  --data "$BODY"
SIG=$(openssl dgst -sha512 -hmac "your-api-secret" gip.csv | awk '{print $2}')

curl -X POST https://demo.zagis.nl/api/zagis/gip \
  -H "x-zagis-key: <your-api-key>" \
  -H "x-zagis-hmac: $SIG" \
  -H "content-type: text/csv" \
  --data-binary @gip.csv

Testing

For an API key and API secret, contact us in good time at info@zagis.nl.