Skip to content
Rate Extra

API authentication with HMAC-SHA256

TravelDistro requests are signed, not tokenised. The Authorization header carries your key ID and a signature over the request; two headers carry the timestamp and a nonce. Bearer tokens are not supported.

What is signed

The signature is an HMAC-SHA256, keyed by your API secret, over six lines joined with a newline:

  1. 01HTTP method, upper case
  2. 02Request path
  3. 03Sorted query string, empty if none
  4. 04Unix timestamp in seconds
  5. 05Nonce, unique per request
  6. 06SHA-256 hex of the request body, of the empty string for GET

Headers

Authorization
TD-HMAC-SHA256 KeyId=<key_id>, Signature=<hex>
X-TD-Timestamp
Unix seconds; must be within 300 s of server time
X-TD-Nonce
Unique per request; a replayed nonce is rejected

Node.js example

import crypto from "node:crypto";

const keyId = process.env.TD_KEY_ID!;
const secret = process.env.TD_SECRET!;

const method = "GET";
const path = "/v1/account";        // request path as sent to the server
const query = "";                  // sorted query string, empty if none
const timestamp = Math.floor(Date.now() / 1000).toString();
const nonce = crypto.randomUUID();
const body = "";
const bodyHash = crypto.createHash("sha256").update(body).digest("hex");

const stringToSign = [method, path, query, timestamp, nonce, bodyHash].join("\n");
const signature = crypto.createHmac("sha256", secret).update(stringToSign).digest("hex");

const res = await fetch("https://api.traveldistro.com" + path, {
  headers: {
    Authorization: `TD-HMAC-SHA256 KeyId=${keyId}, Signature=${signature}`,
    "X-TD-Timestamp": timestamp,
    "X-TD-Nonce": nonce,
  },
});

Confirm the exact path format (with or without the /v1 prefix) against the reference and a test key before you go live; the reference is authoritative.

Rules

  • The timestamp must be within ±300 seconds of server time.
  • A nonce can be used once; replays are rejected.
  • Bearer tokens are not accepted anywhere on the agency API.
  • Keep the secret on your server; never ship it to a browser or mobile app.

Authentication errors

401
Missing, invalid or revoked key
403
IP not in the key's allowlist, agency suspended, or MODULE_NOT_ENABLED
429
RATE_LIMITED; wait Retry-After seconds and resend the same request

Licensed travel agency? Apply for API access.

Get API access