Authenticated Endpoints
Authentication
Authenticated endpoints require users to sign their requests using an API key and API secret.
Below is a guide to authenticating HTTP requests in JavaScript. The example uses the List All Currencies endpoint, but you can easily adapt it to make requests to other endpoints.
Environments
| Environment | URL |
|---|---|
| Prod | https://api.hadron.tether.to |
| Beta | https://api.hadron-beta.tether.to |
const crypto = require("crypto");
const axios = require("axios");
const apiKey = ""; // Paste access Key here
const secretAccessKey = ""; // Paste secret access Key here
// Beta. A key only works in the environment it was created in.
const baseUrl = "https://api.hadron-beta.tether.to";
const method = "GET"; // Upper case
const apiPath = "/v1/issuer/currencies/all"; // The path only. Query parameters go in queryParameters, not in the path.
const queryParameters = {}; // One value per parameter, e.g. { page: 1, limit: 10 }
const body = undefined;
// Any string you never send again. Each nonce is accepted once, across all API keys.
const nonce = crypto.randomUUID();
// Function to flatten and sort object keys for signature generation
const flattenAndSort = (obj, prefix = "") => {
const pairs = [];
for (const key of Object.keys(obj).sort()) {
const fullKey = prefix ? `${prefix}.${key}` : key;
const value = obj[key];
if (typeof value === "object" && value !== null && !Array.isArray(value)) {
pairs.push(...flattenAndSort(value, fullKey));
} else if (value !== null) {
pairs.push(`${fullKey}=${value}`);
}
}
return pairs;
};
// Sign the body as it is sent: the JSON round trip drops undefined fields and turns dates into strings, as the server sees them.
const data = {
nonce,
apiKey,
url: apiPath,
method,
queryParameters,
payload: body === undefined ? {} : JSON.parse(JSON.stringify(body)),
};
// Generate signature
const signaturePayload = flattenAndSort(data).join("&");
const signature = crypto
.createHmac("sha256", secretAccessKey)
.update(signaturePayload)
.digest("hex");
axios({
method,
url: `${baseUrl}${apiPath}`,
params: queryParameters,
headers: {
...(body === undefined ? {} : { "Content-Type": "application/json" }),
"x-api-key": apiKey,
"x-hadron-signature": signature,
"x-nonce": nonce,
},
data: body === undefined ? undefined : JSON.stringify(body),
})
.then((res) => console.log(res.data))
.catch((err) =>
console.error("Request Error:", err.response?.status, err.response?.data ?? err.message)
);
// Errors from the authentication check:
// 403 {"message":"Forbidden"} The API key is not valid on this host (for example a beta key
// on production) or is disabled.
// 500 {"error":"Invalid Api Key"} The API key is not active.
// 500 {"error":"Invalid Signature"} The signed text doesn't match the request: check the method,
// path, query parameters and body.
// 500 {"error":"Invalid Nonce"} The nonce was used before.
// 400 {"errorCode":"INVALID_JSON"} Content-Type: application/json was sent without a body.
Updated 15 days ago
Did this page help you?

