> For the complete documentation index, see [llms.txt](https://docs.skypaybd.top/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.skypaybd.top/integration-and-api/authentication.md).

# Authentication

The SkyPay API implements a robust, multi-tiered authentication framework designed to secure merchant transactions, device communications, and automated services. Every request transmitted to SkyPay must provide valid credentials according to the specific endpoint category.

***

## 1. Header Specifications & Precedence

Authentication across SkyPay endpoints is handled via HTTP request headers. Depending on whether you are interacting with the Payment Gateway, SMS Gateway, or Device Telemetry endpoints, different headers are evaluated.

### Payment Gateway Authentication (Hosted v1 & Headless v2)

Merchant account identity is authenticated via your unique **Brand Key** (issued in your SkyPay merchant dashboard).

| Header / Parameter | Location     | Type   | Status          | Description                                                               |
| ------------------ | ------------ | ------ | --------------- | ------------------------------------------------------------------------- |
| `BRAND-KEY`        | HTTP Header  | String | **Recommended** | Primary header evaluated across all payment endpoints.                    |
| `API-KEY`          | HTTP Header  | String | Supported Alias | Backward-compatible alias for `BRAND-KEY`.                                |
| `SECRET-KEY`       | HTTP Header  | String | Supported Alias | Alternative alias for legacy configurations.                              |
| `Authorization`    | HTTP Header  | String | Supported       | Bearer token format: `Authorization: Bearer <BRAND_KEY>`.                 |
| `api_key`          | Query / Body | String | Fallback Alias  | Allowed in query string or JSON payload (not recommended for production). |

{% hint style="info" %}
**Evaluation Priority**: SkyPay checks for `BRAND-KEY` first, followed by `Authorization: Bearer`, `API-KEY`, `SECRET-KEY`, and finally `api_key` in the request body. Only one valid authentication credential is required per request.
{% endhint %}

### SMS Gateway Authentication

The SMS dispatching endpoint (`/api/v2/gateway/send`) utilizes a dedicated 18-character hardware gateway authorization key.

| Header        | Type   | Status          | Description                                                       |
| ------------- | ------ | --------------- | ----------------------------------------------------------------- |
| `GATEWAY-KEY` | String | **Recommended** | Primary SMS gateway key assigned to your Android hardware bridge. |
| `gateway-key` | String | Supported Alias | Case-insensitive lowercase header.                                |
| `key`         | String | Supported Alias | Short-form key header.                                            |

### Device Telemetry Authentication

The Device Status endpoint (`/api/v2/device/status`) queries hardware operational states using comma-separated device keys.

| Header        | Type   | Required     | Description                                                                     |
| ------------- | ------ | ------------ | ------------------------------------------------------------------------------- |
| `DEVICE-KEYS` | String | **Required** | One or more comma-delimited device identifiers (e.g., `key_dev_01,key_dev_02`). |

***

## 2. Token Security Best Practices

To safeguard your merchant account and prevent unauthorized transaction execution, implement the following security controls:

### 1. Server-Side Environment Storage

Never hardcode API keys or Brand Keys into source code files. Store them in secure server-side environment variables:

```bash
# Production .env configuration
SKYPAY_BRAND_KEY="bk_live_9f83ac0194827dbe10928374a"
SKYPAY_GATEWAY_KEY="gw_a891029384758192"
SKYPAY_API_BASE="https://core.skypaybd.top/api"
```

### 2. Zero Client-Side Exposure

{% hint style="danger" %}
**Never Expose Credentials in Frontend Code**: Never embed your `BRAND-KEY` or `GATEWAY-KEY` in client-facing applications such as browser single-page applications (React, Vue, Angular), mobile applications (Flutter, React Native, iOS, Android), or desktop clients.

All SkyPay API requests must originate from your secure backend server. Client applications should communicate with your own backend API, which securely signs and relays calls to SkyPay.
{% endhint %}

### 3. IP Whitelisting & Origin Guarding

For high-volume enterprise accounts, access to the SkyPay API can be restricted to designated static server IP addresses. Configure trusted IP addresses within your Merchant Portal to prevent compromised keys from being used from rogue hosts.

### 4. Key Rotation & Emergency Revocation

If a Brand Key or Gateway Key is accidentally exposed:

1. Log in to the SkyPay Merchant Portal immediately.
2. Navigate to **API Settings > Credentials**.
3. Generate a new Brand Key.
4. Update your production `.env` configuration and redeploy your service.
5. Deactivate the compromised key immediately.

***

## 3. Authorization Error Responses

If a request fails authentication, SkyPay immediately halts execution and returns an HTTP 401 Unauthorized or HTTP 403 Forbidden status code.

### 1. Missing Authentication Key (HTTP 401)

Returned when no valid authentication header or parameter is detected:

```json
{
  "status": false,
  "message": "BRAND-KEY header is required."
}
```

### 2. Invalid or Inactive Key (HTTP 401)

Returned when the provided key cannot be matched to an active merchant record:

```json
{
  "status": false,
  "message": "Invalid or inactive BRAND-KEY provided."
}
```

### 3. Account Suspended (HTTP 403)

Returned when the merchant account has been locked or suspended by the compliance system:

```json
{
  "status": false,
  "message": "Merchant account is suspended. Contact compliance support."
}
```

***

## 4. Multi-Language Implementation Examples

Below are standard patterns for attaching authentication credentials across common programming languages and HTTP clients.

### cURL

```bash
curl -X POST "https://core.skypaybd.top/api/v2/payment/create"   -H "BRAND-KEY: your_active_brand_key"   -H "Content-Type: application/json"   -H "Accept: application/json"   -d '{
    "cus_name": "Rahim Ahmed",
    "amount": 1200
  }'
```

### Node.js (Axios)

```javascript
const axios = require('axios');

const skypayClient = axios.create({
  baseURL: 'https://core.skypaybd.top/api',
  headers: {
    'BRAND-KEY': process.env.SKYPAY_BRAND_KEY,
    'Content-Type': 'application/json',
    'Accept': 'application/json'
  },
  timeout: 10000
});

async function initiatePayment() {
  try {
    const response = await skypayClient.post('/v2/payment/create', {
      cus_name: 'Rahim Ahmed',
      amount: 1200
    });
    console.log('Session ID:', response.data.id);
  } catch (error) {
    console.error('Authentication or API error:', error.response?.data || error.message);
  }
}
```

### Python (Requests)

```python
import os
import requests

API_URL = "https://core.skypaybd.top/api/v2/payment/create"
BRAND_KEY = os.getenv("SKYPAY_BRAND_KEY", "your_active_brand_key")

headers = {
    "BRAND-KEY": BRAND_KEY,
    "Content-Type": "application/json",
    "Accept": "application/json"
}

payload = {
    "cus_name": "Rahim Ahmed",
    "amount": 1200
}

response = requests.post(API_URL, json=payload, headers=headers, timeout=10)

if response.status_code == 200:
    data = response.json()
    print("Created Session ID:", data.get("id"))
else:
    print(f"Error {response.status_code}:", response.json())
```

### PHP (cURL Native)

```php
<?php

$brandKey = getenv('SKYPAY_BRAND_KEY') ?: 'your_active_brand_key';
$url = 'https://core.skypaybd.top/api/v2/payment/create';

$payload = [
    'cus_name' => 'Rahim Ahmed',
    'amount'   => 1200
];

$ch = curl_init($url);
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_POST           => true,
    CURLOPT_HTTPHEADER     => [
        'BRAND-KEY: ' . $brandKey,
        'Content-Type: application/json',
        'Accept: application/json'
    ],
    CURLOPT_POSTFIELDS     => json_encode($payload),
    CURLOPT_TIMEOUT        => 10
]);

$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

$data = json_decode($response, true);
if ($httpCode === 200 && ($data['status'] ?? false)) {
    echo "Session ID: " . $data['id'];
} else {
    echo "Failed: " . ($data['message'] ?? 'Unknown error');
}
```

***

## 5. Next Steps

With authentication established, review how to initialize customer payment sessions:

* [← Previous: Overview](/readme.md)
* [Next: Create Payment →](/integration-and-api/create-payment.md)
