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

# Authentication

> How to authenticate API requests using Digest Auth

The Ebioro Merchant API uses **HMAC Digest Authentication**. Every request must include three headers that prove you own the API keys.

## Required Headers

| Header               | Description                                     |
| -------------------- | ----------------------------------------------- |
| `X-Digest-Key`       | Your public API key (`pk_...` or `pk_test_...`) |
| `X-Digest-Timestamp` | Current Unix timestamp (seconds)                |
| `X-Digest-Signature` | HMAC-SHA256 signature of the request            |

## Computing the Signature

The signature is an HMAC-SHA256 hash of the concatenation of:

```
path + timestamp + method + body
```

Where:

* `path` — the request path including query string (e.g., `/payments`)
* `timestamp` — the same value as `X-Digest-Timestamp`
* `method` — HTTP method in uppercase (e.g., `POST`, `GET`)
* `body` — the raw JSON body for POST requests, empty string for GET

Signed with your `api_secret_key`.

## Code Examples

<CodeGroup>
  ```javascript Node.js theme={null}
  const crypto = require('crypto');

  function buildAuthHeaders(publicKey, secretKey, path, method, body = '') {
    const timestamp = Math.floor(Date.now() / 1000).toString();
    const data = method !== 'GET' ? JSON.stringify(body) : '';
    const toSign = path + timestamp + method + data;
    const signature = crypto
      .createHmac('sha256', secretKey)
      .update(toSign)
      .digest('hex');

    return {
      'X-Digest-Key': publicKey,
      'X-Digest-Timestamp': timestamp,
      'X-Digest-Signature': signature,
      'Content-Type': 'application/json',
    };
  }
  ```

  ```python Python theme={null}
  import hmac
  import hashlib
  import time
  import json

  def build_auth_headers(public_key, secret_key, path, method, body=None):
      timestamp = str(int(time.time()))
      data = json.dumps(body) if body and method != 'GET' else ''
      to_sign = path + timestamp + method + data
      signature = hmac.new(
          secret_key.encode(),
          to_sign.encode(),
          hashlib.sha256
      ).hexdigest()

      return {
          'X-Digest-Key': public_key,
          'X-Digest-Timestamp': timestamp,
          'X-Digest-Signature': signature,
          'Content-Type': 'application/json',
      }
  ```

  ```php PHP theme={null}
  function buildAuthHeaders($publicKey, $secretKey, $path, $method, $body = '') {
      $timestamp = (string) time();
      $data = $method !== 'GET' ? json_encode($body) : '';
      $toSign = $path . $timestamp . $method . $data;
      $signature = hash_hmac('sha256', $toSign, $secretKey);

      return [
          'X-Digest-Key' => $publicKey,
          'X-Digest-Timestamp' => $timestamp,
          'X-Digest-Signature' => $signature,
          'Content-Type' => 'application/json',
      ];
  }
  ```
</CodeGroup>

## Timestamp Validation

The server rejects requests where the timestamp is more than **5 minutes** from the server's current time. Make sure your server clock is synchronized.

## Errors

| Status | Reason                                    |
| ------ | ----------------------------------------- |
| 401    | Missing header values                     |
| 401    | Invalid public key                        |
| 401    | Signature verification failed             |
| 401    | The request timed out (timestamp too old) |
