Signing

To ensure the security of your account, all requests to private endpoints must be digitally signed. A signature is a cryptographic process that proves to QuBit that a request was genuinely sent by you (the holder of the Secret Key) and that its content has not been tampered with during transit.

💡 SDK Recommended

We strongly recommend using our official SDKs to interact with the API. The SDKs handle all the complex signing logic for you, which can significantly reduce development time and the possibility of errors.

If you need to implement the signing process yourself, please follow this guide carefully. An incorrect signature will result in an authentication failure (401 Unauthorized), and debugging can be challenging due to the various potential causes of a signature mismatch.


Signing Process Overview

The QuBit signing process consists of the following three steps:

  1. Construct the Prehash String

  2. Compute the HMAC-SHA256 Hash using your Secret Key

  3. Base64-Encode the Hash Result

Step 1: Construct the Prehash String

The prehash string (stringToSign) is a plain text string created by concatenating four components of your request in a strict order.

Concatenation Rule: timestamp + method + requestPath + body

  • timestamp (String):

    • REST API: The ISO 8601 formatted UTC timestamp string you are sending in the Qubit-Api-Timestamp header, e.g., "2025-07-16T10:30:00.123Z".

    • WebSocket Auth: The value of the timestamp field in the args of your login message.

  • method (String):

    • REST API: The uppercase HTTP request method, e.g., "GET" or "POST".

    • WebSocket Auth: The fixed value "GET".

  • requestPath (String):

    • REST API: The path of the request, excluding the domain and query parameters. For https://api.qubit.com/api/v1/trade/order?a=1, the requestPath is "/api/v1/trade/order".

    • WebSocket Auth: The fixed value "/users/ws/auth".

  • body (String):

    • For GET or DELETE requests, the body component is an empty string "".

    • For POST or PUT requests, the body is the full, unmodified JSON request body string. If the request body is empty (e.g., {}), the body is "{}".

Pseudocode Example (REST API):


Step 2: HMAC-SHA256 Hash

Use your Secret Key as the HMAC key to compute the HMAC-SHA256 hash of the prehash string (stringToSign).

  • Input: stringToSign (from Step 1), Secret Key (the private key you received when creating the API Key)

  • Algorithm: HMAC-SHA256

  • Output: A binary hash digest.


Step 3: Base64 Encoding

Take the binary hash digest generated in the previous step and encode it using standard Base64 encoding to get the final signature string.

This Base64-encoded string is the value you need to include in the Qubit-Api-Signature header of your request.


Common Errors & Debugging Tips

If your requests are consistently met with a 401 Unauthorized response with msg: "invalid signature", please check for these common mistakes:

  1. Incorrect Prehash String (stringToSign) Concatenation:

    • Wrong Order: Ensure the strict order of timestamp + method + requestPath + body.

    • Extra Content in requestPath: Make sure requestPath does not include the ? and any subsequent query parameters.

    • Body Mismatch:

      • For POST requests, the body string used for signing must be byte-for-byte identical to the request body you actually send. An extra space or a different field order in the JSON will result in a different signature. It's recommended to generate the JSON string first, use it for signing, and then send that exact string as the request body.

      • For GET requests, ensure the body component is an empty string "", not null or {}.

  2. Timestamp Issues:

    • Ensure the timestamp used for signing is exactly the same as the one sent in the request header.

    • Ensure the timestamp is in UTC and formatted as ISO 8601, including milliseconds if your language/library supports it.

  3. Encoding Problems:

    • Ensure all strings are UTF-8 encoded.

    • Make sure you are Base64-encoding the raw binary output of the HMAC-SHA256 function, not its hexadecimal (Hex) representation.

Debugging Suggestion: In your code, print the final, concatenated stringToSign before it's hashed. Then, use an online HMAC-SHA256 tool to manually compute the signature with your stringToSign and Secret Key. Base64-encode the raw output and see if it matches what your program generates.

Last updated