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

# Authentication

## Overview

Every request to the Onboard Business API must include your API key and an
HMAC-SHA256 request signature — there is no unsigned tier.

```http theme={null}
x-api-key: <your-api-key>
```

<Warning>
  API keys used to call cash payment or crypto transfer endpoints must have
  IP whitelisting configured in the [Business Dashboard](https://business.onboard.xyz).
  Requests from an unlisted IP are rejected. See
  [Getting API Credentials](/guides/api-concepts/api-credentials).
</Warning>

## Signing a request

Required headers for signed requests:

| Header        | Description                                               |
| ------------- | --------------------------------------------------------- |
| `x-api-key`   | Your API key, from the Business Dashboard                 |
| `x-signature` | HMAC-SHA256 signature of the request                      |
| `x-timestamp` | Unix timestamp (seconds) when the signature was generated |

The signature is computed over the timestamp and the exact JSON body you send,
joined with `&`:

```javascript theme={null}
const crypto = require('crypto');

const timestamp = Math.ceil(Date.now() / 1000);
const apiSecret = '<your Onboard Business API secret>'; // from the Business Dashboard
const requestBody = { /* the exact JSON body of your request; {} for GET requests */ };

const signaturePayload = `t=${timestamp}&${JSON.stringify(requestBody)}`;
const signature = crypto
  .createHmac('sha256', apiSecret)
  .update(signaturePayload)
  .digest('hex');
```

Include the computed values in your request headers:

```http theme={null}
x-api-key: <your-api-key>
x-signature: <computed-signature>
x-timestamp: <epoch-timestamp>
```

<Note>
  Your timestamp must be within **30 seconds** of the current time — if
  requests are unexpectedly rejected, check for clock drift on the machine
  generating the signature.
</Note>

<Warning>
  **Unauthorized requests** return a `401` status, whether the cause is a
  missing/invalid `x-api-key` or an invalid/expired signature. For example, a
  skewed timestamp returns:

  ```json theme={null}
  {
    "code": "UNAUTHENTICATED",
    "message": "Request timestamp is skewed beyond 30 seconds"
  }
  ```

  Check the `message` field for the specific error.
</Warning>
