Get started

Cupid also provides a secure method for authenticating requests without directly transmitting your private API key. Instead, you can sign your request using HMAC SHA-512 and include the signature along with a public key in the request headers. This ensures better security by preventing your private key from being exposed in transit.

Why Use Secure Authentication?

When using API keys directly, they can be intercepted in transit, stored insecurely, or inadvertently exposed in logs. Instead, using a signed request ensures:

  • Enhanced Security: Your private API key never leaves your system.
  • Replay Attack Prevention: Each request includes a timestamp to prevent reuse of old signatures.
  • Integrity Assurance: The server verifies that the request has not been tampered with.

How It Works

Instead of sending your private API key, you generate a unique signature using your API key, a shared secret, and a timestamp. The server then verifies the signature to authenticate the request.

Steps:

  1. Generate a UNIX timestamp.
  2. Create a signature using HMAC SHA-512, combining your API key, shared secret, and timestamp.
  3. Include the public key, signature, and timestamp in the request headers.
  4. The server validates the signature and processes the request.

Example Implementation (JavaScript/Node.js)

const crypto = require("crypto");

const privateApiKey = "prod_123";
const publicApiKey = "prod_public_456";

const timestamp = Math.floor(Date.now() / 1000);
const signature = crypto.SHA512(`${privateApiKey}${publicApiKey}${timestamp}`).toString(crypto.enc.Hex);

const authHeaderValue = `PublicKey=${publicKey},Signature=${signature},Timestamp=${timestamp}`;

const headers = {
  "Content-Type": "application/json",
  Accept: "application/json",
  Authorization: authHeaderValue
};

console.log(headers);
import hashlib
import time

private_api_key = "prod_123"
public_api_key = "prod_public_456"

timestamp = str(int(time.time()))
signature_string = f"{private_api_key}{public_api_key}{timestamp}"

# Generate SHA-512 hash
signature = hashlib.sha512(signature_string.encode()).hexdigest()

auth_header_value = f"PublicKey={public_api_key},Signature={signature},Timestamp={timestamp}"

headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
    "Authorization": auth_header_value
}

print(headers)
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.time.Instant;

public class ApiAuthHeader {
    public static void main(String[] args) {
        String privateApiKey = "prod_123";
        String publicApiKey = "prod_public_456";
        
        long timestamp = Instant.now().getEpochSecond();
        String signatureString = privateApiKey + publicApiKey + timestamp;
        
        String signature = generateSHA512Hash(signatureString);

        String authHeaderValue = "PublicKey=" + publicApiKey + ",Signature=" + signature + ",Timestamp=" + timestamp;
        
        System.out.println("Headers:");
        System.out.println("Content-Type: application/json");
        System.out.println("Accept: application/json");
        System.out.println("Authorization: " + authHeaderValue);
    }

    private static String generateSHA512Hash(String input) {
        try {
            MessageDigest md = MessageDigest.getInstance("SHA-512");
            byte[] hashBytes = md.digest(input.getBytes(StandardCharsets.UTF_8));
            StringBuilder hexString = new StringBuilder();
            for (byte b : hashBytes) {
                String hex = Integer.toHexString(0xff & b);
                if (hex.length() == 1) hexString.append('0');
                hexString.append(hex);
            }
            return hexString.toString();
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException("SHA-512 Algorithm not found", e);
        }
    }
}

Example HTTP Request

GET /v3.0/property/search HTTP/1.1
Host: content-api.cupid.travel
Content-Type: application/json
Accept: application/json
Authorization: PublicKey=123,Signature=abcdef123456789,Timestamp=1610000000