> ## Documentation Index
> Fetch the complete documentation index at: https://docs.roxom.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Authentication

> Learn how to authenticate your API requests using API keys

## Overview

Some Roxom API endpoints which access protected account's data require authentication. You'll be provided with an API key, a private key and the algorithm used to generate the keys pair. Each request to these endpoints must include your API Key and a private key's signature to verify the request integrity.

Currently, Roxom only supports **RSA-2048** algorithm and PKCS#8-encoded private keys to authenticate protected endpoints.

<Note>
  Roxom **DOES NOT** store your private key. We DO only store your API Key ID and the public key associated with your private key in order to verify your requests.
</Note>

<Warning>
  Keep your API key and your private key secure and never expose them in client-side code or public repositories. If you lose your private key, you will need to generate a new API key and you will be provided with a new private key.
</Warning>

## Authentication Method

Each request requires:

1. **API Key**: Your API Key. Example: "xrxk\_key\_3437401edb0560e2de84efe7d34327c4" (the format may vary)
2. **Request Signature**: A base64-encoded RSA signature of the payload using your private key. The payload must be hashed using the SHA-256 algorithm, and then the digest must be signed using your private key.

### Required Headers

```http theme={null}
X-API-Key: your_api_key_here
X-API-Signature: base64_encoded_rsa_signature
Content-Type: application/json
```

With actual values:

```http theme={null}
X-API-Key: xrxk_key_3437401edb0560e2de84efe7d34327c4
X-API-Signature: qWZsftLfICoJ0hPkuipsX9q0hsLJoSNNnZvBUdrg8tOSxuYwIfmoIZ4zRzyXLvW7HFj+TC0i8Dt35LY3tsYgd07QT3/A6Oi4CBpeUVSZULDCYcA38YX+uEKPs9/la44Ncq2iL75C2tfDls7wI1o5dd9skkyWgc9QXVMhwQKS0Pu4KPGAl7Zm30ZrKUFnDBSXMCg/Jx9kS7U/BVhHVK6C6zEB5OWdDCKdf7uvqEtJ/rKVSkMO9byeNWzMYRsnZnpyKdzVgZsGOcDa8JqtKm0CmxLqiHnufqUqdvCF6zwVuSUKvwgQrIv3NrJzSCqkUhStETpzWzsZixRS3MI8yHzUZg==
```

## Payload Generation

The payload that you MUST hash to then sign is the string representation of the request HTTP method (in uppercase), path (including query parameters e.g. `?includeClosed=true`), and body payload (if any), concatenated with a colon (`:`) as a separator. Every parameter MUST be hashed as it's sent in the request. Body parameters must be alphabetically sorted by key and concatenated with an ampersand (`&`) as a separator.

<Note>
  Body parameters that are null MUST be excluded from the payload.
</Note>

### Examples

**GET Request with no body:**

```
Payload: "GET:/api/v1/accounts/balance"
```

**GET Request with query parameters and no body:**

```
Payload: "GET:/api/v1/orders?includeClosed=true"
```

**POST Request with body:**

```json theme={null}
Body: {"symbol": "BTCUSDT", "qty": 100, "isBuy": true}
Payload: "POST:/api/v1/orders:isBuy=true&qty=100&symbol=BTCUSDT"
```

**POST Request with body and query parameters:**

```json theme={null}
Body: {"symbol": "BTCUSDT", "qty": 100, "isBuy": true}
Payload: "POST:/api/v1/orders?anyQueryParam=true:isBuy=true&qty=100&symbol=BTCUSDT"
```

### Example Request

The below command is assuming that you have your Roxom private key stored in a file named `priv.pem`:

```bash theme={null}
echo -n 'GET:/api/v1/orders' \
  | openssl dgst -sha256 -sign priv.pem \
  | openssl enc -base64 -A

qWZsftLfICoJ0hPkuipsX9q0hsLJoSNNnZvBUdrg8tOSxuYwIfmoIZ4zRzyXLvW7HFj+TC0i8Dt35LY3tsYgd07QT3/A6Oi4CBpeUVSZULDCYcA38YX+uEKPs9/la44Ncq2iL75C2tfDls7wI1o5dd9skkyWgc9QXVMhwQKS0Pu4KPGAl7Zm30ZrKUFnDBSXMCg/Jx9kS7U/BVhHVK6C6zEB5OWdDCKdf7uvqEtJ/rKVSkMO9byeNWzMYRsnZnpyKdzVgZsGOcDa8JqtKm0CmxLqiHnufqUqdvCF6zwVuSUKvwgQrIv3NrJzSCqkUhStETpzWzsZixRS3MI8yHzUZg==
```

```bash theme={null}
# Generate signature first, then make request
curl -X GET "https://api.roxom.com/api/v1/accounts/balance" \
  -H "X-API-Key: xrxk_key_3437401edb0560e2de84efe7d34327c4" \
  -H "X-API-Signature: qWZsftLfICoJ0hPkuipsX9q0hsLJoSNNnZvBUdrg8tOSxuYwIfmoIZ4zRzyXLvW7HFj+TC0i8Dt35LY3tsYgd07QT3/A6Oi4CBpeUVSZULDCYcA38YX+uEKPs9/la44Ncq2iL75C2tfDls7wI1o5dd9skkyWgc9QXVMhwQKS0Pu4KPGAl7Zm30ZrKUFnDBSXMCg/Jx9kS7U/BVhHVK6C6zEB5OWdDCKdf7uvqEtJ/rKVSkMO9byeNWzMYRsnZnpyKdzVgZsGOcDa8JqtKm0CmxLqiHnufqUqdvCF6zwVuSUKvwgQrIv3NrJzSCqkUhStETpzWzsZixRS3MI8yHzUZg==" \
  -H "Content-Type: application/json"
```

## Error Responses

If authentication fails, you will receive one of the following error responses:

### Missing API Key

```json theme={null}
{
  "error": 400,
  "message": "Api key header not provided"
}
```

### Missing Signature

```json theme={null}
{
  "error": 400,
  "message": "Signature header not provided"
}
```

### Invalid API Key

```json theme={null}
{
  "error": 401,
  "message": "Unauthorized"
}
```

### Invalid Signature

```json theme={null}
{
  "error": 401,
  "message": "Unauthorized"
}
```

## Best Practices

<AccordionGroup>
  <Accordion title="Store API Keys Securely">
    Follow these security practices for API key management:

    * **Use environment variables** to store API keys and private keys
    * **Never commit API keys and private keys** to version control systems
    * **Rotate API keys and private keys regularly** as part of your security policy
    * **Restrict API key access** to only necessary team members

    <Warning>
      Compromised API keys can lead to unauthorized trading activity. Treat them like passwords.
    </Warning>
  </Accordion>

  <Accordion title="Handle Authentication Errors">
    Implement robust error handling for authentication failures:

    * **Implement proper error handling** for 401 responses
    * **Log authentication failures** for security monitoring
    * **Have a strategy for API key rotation** and seamless updates
    * **Set up alerts** for repeated authentication failures
  </Accordion>
</AccordionGroup>

## Next Steps

<Card title="Base URLs" icon="globe" href="/api-reference/base-urls">
  Configure your application with the correct API endpoints
</Card>
