How to Correctly Sign OKX API Requests to Avoid "Invalid Signature" Errors

ยท

Understanding OKX API Authentication

When working with OKX's REST API for private endpoints, proper authentication is crucial. All requests must include specific headers and follow a precise signing process to avoid the common "Invalid Sign" error (Code 50113).

Required Request Headers

Every private API call to OKX must contain these headers:

For simulated trading, add:

๐Ÿ‘‰ Learn more about API authentication best practices

The Signature Generation Process

Creating a valid signature involves these steps:

  1. Concatenate these components:

    • Timestamp (same as OK-ACCESS-TIMESTAMP)
    • HTTP method in uppercase (GET/POST/PUT/DELETE)
    • Request path (e.g., /api/v5/account/balance)
    • Request body (for POST/PUT requests)
  2. Create HMAC SHA256 hash using your Secret Key
  3. Base64-encode the resulting hash

Signature Formula

sign = Base64.encode(HMAC_SHA256(timestamp + method + requestPath + body, secretKey))

Common Pitfalls and Solutions

Many developers encounter the "Invalid Signature" error due to:

  1. Timestamp format issues

    • Must use ISO 8601 format with milliseconds
    • Example: 2023-03-15T08:12:45.123Z
  2. Method case sensitivity

    • Always use uppercase (GET, not get)
  3. Path inconsistencies

    • Include full path with query parameters for GET requests
    • Example: /api/v5/account/balance?ccy=BTC
  4. Body handling mistakes

    • For GET requests with no body: omit it
    • For POST: include raw JSON string (unformatted)
  5. Secret key errors

    • Using wrong key (check API dashboard)
    • Extra spaces in key string

Working Code Example

Here's how to properly structure a balance check request:

import hashlib
import hmac
import base64
import time
import requests

api_key = "YOUR_API_KEY"
secret_key = "YOUR_SECRET_KEY"
passphrase = "YOUR_PASSPHRASE"

timestamp = time.strftime("%Y-%m-%dT%H:%M:%S.000Z", time.gmtime())
method = "GET"
request_path = "/api/v5/account/balance"

# Create signature
message = timestamp + method + request_path
signature = base64.b64encode(
    hmac.new(
        secret_key.encode("utf-8"),
        message.encode("utf-8"),
        hashlib.sha256
    ).digest()
).decode("utf-8")

headers = {
    "OK-ACCESS-KEY": api_key,
    "OK-ACCESS-SIGN": signature,
    "OK-ACCESS-TIMESTAMP": timestamp,
    "OK-ACCESS-PASSPHRASE": passphrase,
    "x-simulated-trading": "1"  # For sandbox
}

response = requests.get(
    "https://www.okx.com" + request_path,
    headers=headers
)

๐Ÿ‘‰ Explore OKX API documentation for advanced implementations

FAQ: Solving Signature Problems

Why does my API call return "Invalid Sign"?

This typically indicates:

How do I verify my signature is correct?

  1. Compare against OKX's example signatures
  2. Use online HMAC SHA256 generators to validate
  3. Check timestamp precision (milliseconds matter)

Should GET request parameters be in the path or body?

All GET parameters belong in the request path:

/api/v5/account/balance?ccy=BTC

Why does my sandbox request fail?

Ensure you:

  1. Added x-simulated-trading: 1 header
  2. Are using sandbox API endpoints
  3. Created sandbox-specific API keys

How often should I rotate my API keys?

For security:

Best Practices for API Security

  1. Key management

    • Never expose secret keys in client-side code
    • Store keys in secure environment variables
  2. Request validation

    • Verify response signatures
    • Implement request rate limiting
  3. Error handling

    • Gracefully handle 50113 errors
    • Implement automatic retry with backoff

By following these guidelines and ensuring proper signature generation, you'll avoid common authentication issues and build reliable integrations with OKX's trading API.