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

# HMAC Signing

> How to calculate the Authorization header

HMAC is required when you call `POST /application/connect` with a `callback` URL. It proves the request came from your server.

## Headers

All HMAC-authenticated requests need:

| Header          | Value                          |
| --------------- | ------------------------------ |
| `api-key`       | Your master api-key            |
| `Authorization` | `HMAC {timestamp}:{signature}` |
| `Content-Type`  | `application/json`             |

## How to Calculate the Signature

<Steps>
  <Step title="Get the current UNIX timestamp">
    ```javascript theme={null}
    const time = Date.now().toString();
    ```
  </Step>

  <Step title="MD5-hash the request body">
    ```javascript theme={null}
    const contentHash = crypto.createHash('md5')
      .update(JSON.stringify(body))
      .digest('hex');
    ```

    For GET requests with no body, hash `{}` — this gives `99914b932bd37a50b983c5e7c90ae93b`.
  </Step>

  <Step title="Concatenate timestamp + method + path + body hash">
    ```javascript theme={null}
    const signatureRawData = time + 'POST' + '/api/v0/application/connect' + contentHash;
    ```
  </Step>

  <Step title="Create HMAC-SHA256 with your API secret">
    ```javascript theme={null}
    const signature = crypto.createHmac('sha256', apiSecret)
      .update(signatureRawData)
      .digest('hex');
    ```
  </Step>

  <Step title="Assemble the Authorization header">
    ```javascript theme={null}
    const authorization = 'HMAC ' + time + ':' + signature;
    ```
  </Step>
</Steps>

## Complete Example (Node.js)

```javascript theme={null}
import crypto from 'crypto';

const apiSecret = ''; // Your API Secret
const time = Date.now().toString();
const method = 'POST';
const path = '/api/v0/application/connect';
const body = {
  email: 'user@example.com',
  callback: 'https://yourapp.com/webhooks',
  ref: 'user-123',
};

// MD5 hash of the body
const contentHash = crypto
  .createHash('md5')
  .update(JSON.stringify(body))
  .digest('hex');

// Signature input
const signatureRawData = time + method + path + contentHash;

// HMAC SHA256
const signature = crypto
  .createHmac('sha256', apiSecret)
  .update(signatureRawData)
  .digest('hex');

// Final header
const authorization = 'HMAC ' + time + ':' + signature;
```

<CodeGroup>
  ```python Python theme={null}
  import hashlib, hmac, json, time

  api_secret = ''  # Your API Secret
  timestamp = str(int(time.time() * 1000))
  method = 'POST'
  path = '/api/v0/application/connect'
  body = {'email': 'user@example.com', 'callback': 'https://yourapp.com/webhooks'}

  content_hash = hashlib.md5(json.dumps(body).encode()).hexdigest()
  signature_input = timestamp + method + path + content_hash
  signature = hmac.new(api_secret.encode(), signature_input.encode(), hashlib.sha256).hexdigest()

  authorization = f'HMAC {timestamp}:{signature}'
  ```

  ```bash curl theme={null}
  TIMESTAMP=$(date +%s%3N)
  BODY='{"email":"user@example.com","callback":"https://yourapp.com/webhooks"}'
  CONTENT_HASH=$(echo -n "$BODY" | md5sum | awk '{print $1}')
  SIG_INPUT="${TIMESTAMP}POST/api/v0/application/connect${CONTENT_HASH}"
  SIGNATURE=$(echo -n "$SIG_INPUT" | openssl dgst -sha256 -hmac "$SECRET" | awk '{print $NF}')

  curl -X POST "https://dev.bringin.xyz/api/v0/application/connect" \
    -H "api-key: YOUR_MASTER_KEY" \
    -H "Authorization: HMAC ${TIMESTAMP}:${SIGNATURE}" \
    -H "Content-Type: application/json" \
    -d "$BODY"
  ```
</CodeGroup>

## Time Window

The timestamp must be within **600 seconds** (10 minutes) of the server's time. Requests outside this window are rejected.
