Authentication & Signing

Every request uses the merchant API key together with a signed HMAC SHA256 payload. Requests with missing headers, invalid signatures, stale timestamps, or reused nonces will be rejected.

  • Algorithm: HMAC SHA256
  • Secret: raw merchant API key
  • Digest output: lowercase hex string
  • Timestamp window: 5 minutes
  • Nonce: must be unique for every request
  • This API follows a RESTful style and uses HTTP POST with JSON request bodies.

Headers

Header
Required
Example value
Explanation
Content-Type
Yes
application/json
JSON request body.
x-api-key
Yes
<merchant_api_key>
Raw API key issued by Yuter.
x-timestamp
Yes
<unix_ms>
Current Unix timestamp in milliseconds. Requests older than 5 minutes are rejected.
x-nonce
Yes
<unique_random_string>
Unique value per request. Reused nonces are rejected.
x-signature
Yes
<hex_hmac_sha256>
HMAC SHA256 signature built from method, path, timestamp, nonce, and raw JSON body.

Signature payload

POST
/api/integrations/merchant/bookings/redeem
<timestamp>
<nonce>
{"bookingId":"<booking_id>"}

Use the exact HTTP method, exact request path, exact timestamp, exact nonce, and exact raw JSON body. The JSON body used for signing must match the body sent over HTTP byte-for-byte.

RESTful request example

POST /api/integrations/merchant/bookings/redeem HTTP/1.1
Host: www.yuterwellness.com
Content-Type: application/json
x-api-key: <merchant_api_key>
x-timestamp: <unix_ms>
x-nonce: <unique_random_string>
x-signature: <hex_hmac_sha256>

{"bookingId":"69ce982e96a5b33a356abab0"}

Node.js signing example

import crypto from 'crypto';

function buildSigningPayload({ method, path, timestamp, nonce, body }) {
  return [method.toUpperCase(), path, timestamp, nonce, body].join('\n');
}

function createMerchantRequest({ apiKey, bookingId }) {
  const path = '/api/integrations/merchant/bookings/redeem';
  const method = 'POST';
  const timestamp = String(Date.now());
  const nonce = crypto.randomUUID();
  const body = JSON.stringify({ bookingId });

  const signature = crypto
    .createHmac('sha256', apiKey)
    .update(buildSigningPayload({ method, path, timestamp, nonce, body }))
    .digest('hex');

  return {
    url: `https://www.yuterwellness.com${path}`,
    method,
    headers: {
      'Content-Type': 'application/json',
      'x-api-key': apiKey,
      'x-timestamp': timestamp,
      'x-nonce': nonce,
      'x-signature': signature,
    },
    body,
  };
}