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

# Authentication

> Learn how to authenticate with Caibo IPG APIs using API keys generated from the Control Panel

# Overview

Caibo IPG uses a two-tier authentication system where merchants first authenticate through the Control Panel to generate API keys, then use those API keys to access payment APIs. This approach provides secure access management while maintaining ease of integration.

For browser-side flows (the embedded checkout iframe), the API key is **never** sent to the browser. Instead the merchant backend exchanges it for a short-lived **checkout session token** scoped to a single payment request. See [Checkout Session Tokens](#checkout-session-tokens-browser-side-flows) below.

## Authentication Architecture

### Control Panel Authentication

The Caibo Control Panel (merchant back office) handles user authentication and API key management. Merchants log into the control panel to manage their account and generate API keys for programmatic access.

### API Key Authentication

Generated API keys are used to authenticate **server-to-server** requests to Caibo IPG payment APIs. These keys are included in HTTP headers for secure API access. The `apiKey` is a long-lived bearer secret and must never appear in browser URLs, client-side code, or any value that can leave your server.

### Checkout Session Token Authentication

For the embedded checkout iframe — where the merchant `apiKey` cannot be used directly — your backend mints a short-lived (15-minute) **checkout session token** that is bound to a single payment request. The browser uses that token to authenticate against a small allow-list of endpoints. See [Checkout Session Tokens](#checkout-session-tokens-browser-side-flows).

## Getting Started

### Step 1: Access the Control Panel

Navigate to the Caibo Control Panel and log in with your merchant credentials.

**Login Endpoint**: `POST /auth/login`

**Request:**

```json theme={null}
{
  "email": "merchant@example.com",
  "password": "your-secure-password"
}
```

**Response:**

```json theme={null}
{
  "accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "expireDate": "2024-01-15T10:30:00Z"
}
```

### Step 2: Generate API Key

Once logged into the control panel, navigate to your profile section to generate or regenerate your API key.

**API Key Generation Endpoint**: `PUT /users/{userId}/apikey`

**Headers:**

```
Authorization: Bearer {accessToken}
```

**Response:**

```json theme={null}
"caibo_live_sk_1234567890abcdef"
```

### Step 3: Use API Key in Payment Requests

Include your API key in all payment API requests using the `X-API-Key` header.

**Example Payment Request:**

```bash theme={null}
curl -X POST \
  "https://apay.caibo.digital/payment-requests" \
  -H "X-API-Key: caibo_live_sk_1234567890abcdef" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": 100.00,
    "currency": "EUR",
    "reference": "ORDER-12345"
  }'
```

## API Key Management

### Key Types

Caibo provides different API key types based on your environment:

* **Live Keys**: `caibo_live_sk_*` - For production transactions
* **Test Keys**: `caibo_test_sk_*` - For development and testing

### Security Best Practices

#### Key Storage

* **Never expose API keys** in client-side code or public repositories
* **Store keys securely** in environment variables or secure configuration
* **Use different keys** for different environments (development, staging, production)

#### Key Rotation

* **Regenerate keys regularly** for enhanced security
* **Update all integrations** when rotating keys
* **Monitor key usage** through the control panel

#### Access Control

* **Limit key permissions** to required operations only
* **Monitor API key usage** for suspicious activity
* **Revoke compromised keys** immediately

### Regenerating API Keys

To regenerate your API key:

1. **Log into the Control Panel**
2. **Navigate to Profile Settings**
3. **Click "Re-generate API Key"**
4. **Confirm the action** (old key will be invalidated)
5. **Update your integrations** with the new key

**Warning**: Regenerating an API key immediately invalidates the previous key. Ensure all integrations are updated before regenerating.

## Checkout Session Tokens (Browser-Side Flows)

The **embedded checkout iframe** runs in the customer's browser, where the merchant `apiKey` cannot be used directly — leaking it would compromise the entire account. To authenticate the iframe safely, your backend exchanges the `apiKey` for a **short-lived, scoped token**:

| Property                 | Merchant `apiKey`                    | Checkout session token                                |
| ------------------------ | ------------------------------------ | ----------------------------------------------------- |
| Lifetime                 | Long-lived (until rotated)           | **15 minutes**                                        |
| Scope                    | Full merchant API                    | One payment request + a small endpoint allow-list     |
| Where to send it         | `X-API-Key` header, server-to-server | `X-Checkout-Token` header, or `?token=` in iframe URL |
| Can it mint more tokens? | n/a                                  | **No**                                                |

### Minting a Token

Your backend calls the mint endpoint after creating the payment request:

```bash theme={null}
curl -X POST \
  "https://apay.caibo.digital/payment-requests/{paymentRequestId}/checkout-session" \
  -H "X-API-Key: caibo_live_sk_1234567890abcdef" \
  -H "Content-Type: application/json" \
  -d '{}'
```

**Response:**

```json theme={null}
{
  "token": "bhMlOWTW16rHxnmOugI9Uu1qNJk4IzD0-EZfGsRLJDU",
  "paymentRequestId": 17784899067150744,
  "expiresAt": "2026-05-11T13:25:33Z",
  "ttlSeconds": 900
}
```

Your server then returns `{ requestId, token }` to the browser (over your own authenticated channel) and the frontend constructs:

```text theme={null}
https://pay.caibo.digital/main?requestId=REQUEST_ID&token=TOKEN
```

This URL is safe to use as the iframe `src`: a leak only compromises one payment request for 15 minutes, not the whole account.

<Warning>
  Never pass `apiKey=` in the iframe URL. The legacy `?apiKey=` parameter still works for backward compatibility but emits a console deprecation warning on every checkout-page load. Migrate to `?token=` — exposing the `apiKey` to the browser is treated as a credential leak.
</Warning>

For the full reference (endpoint behavior, response shape, allow-listed endpoints, error codes, lifecycle), see the [Mint a Checkout Session Token](/ipg/iframe-checkout/checkout-session-token) page.

## Authentication Headers

### Required Headers (server-to-server)

Most server-to-server Caibo IPG API requests must include the following headers:

```http theme={null}
X-API-Key: your-api-key-here
Content-Type: application/json
```

### Required Headers (embedded checkout)

Requests originating from inside the embedded checkout iframe authenticate with a [checkout session token](#checkout-session-tokens-browser-side-flows) instead. The Caibo payment page sets this header automatically once it picks up `?token=` from the iframe URL; you only need to set it manually if you call the API from a non-browser client using a token.

```http theme={null}
X-Checkout-Token: bhMlOWTW16rHxnmOugI9Uu1qNJk4IzD0-EZfGsRLJDU
Content-Type: application/json
```

<Note>
  Exactly one of `X-API-Key` or `X-Checkout-Token` is expected per request. If both are present, the checkout token takes precedence and the request is treated as a scoped (`checkout_session`) call.
</Note>

### Optional Headers

Additional headers for enhanced functionality:

```http theme={null}
X-Idempotency-Key: unique-request-id
X-Webhook-Signature: signature-for-verification
```

## Error Handling

### Authentication Errors

#### 401 Unauthorized

```json theme={null}
{
  "error": "Invalid API key",
  "code": "INVALID_API_KEY",
  "message": "The provided API key is invalid or has been revoked"
}
```

**Common Causes:**

* Invalid or expired API key
* Missing `X-API-Key` header
* Revoked or regenerated key

**Resolution:**

* Verify your API key is correct
* Check that the key hasn't been regenerated
* Ensure the header is properly formatted

#### 403 Forbidden

```json theme={null}
{
  "error": "Insufficient permissions",
  "code": "INSUFFICIENT_PERMISSIONS", 
  "message": "Your API key does not have permission for this operation"
}
```

**Common Causes:**

* API key lacks required permissions
* Account limitations or restrictions
* Suspended merchant account

**Resolution:**

* Contact support to verify account status
* Check account permissions in control panel
* Ensure compliance with terms of service

## Testing Authentication

### Test Your API Key

Use this simple endpoint to verify your API key is working:

```bash theme={null}
curl -X GET \
  "https://apay.caibo.digital/ping" \
  -H "X-API-Key: your-api-key-here"
```

**Success Response:**

```json theme={null}
{
  "status": "ok",
  "message": "API key is valid",
  "timestamp": "2024-01-15T10:30:00Z"
}
```

### Webhook Authentication

For webhook endpoints, Caibo includes signature verification:

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

function verifyWebhookSignature(payload, signature, secret) {
  const expectedSignature = crypto
    .createHmac('sha256', secret)
    .update(payload)
    .digest('hex');
  
  return signature === expectedSignature;
}
```

## Integration Examples

### Node.js Example

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

const caiboClient = axios.create({
  baseURL: 'https://apay.caibo.digital',
  headers: {
    'X-API-Key': process.env.CAIBO_API_KEY,
    'Content-Type': 'application/json'
  }
});

// Create payment request
async function createPayment(paymentData) {
  try {
    const response = await caiboClient.post('/payment-requests', paymentData);
    return response.data;
  } catch (error) {
    if (error.response?.status === 401) {
      throw new Error('Invalid API key - please check your credentials');
    }
    throw error;
  }
}
```

### PHP Example

```php theme={null}
<?php
class CaiboClient {
    private $apiKey;
    private $baseUrl = 'https://apay.caibo.digital';
    
    public function __construct($apiKey) {
        $this->apiKey = $apiKey;
    }
    
    public function createPayment($paymentData) {
        $headers = [
            'X-API-Key: ' . $this->apiKey,
            'Content-Type: application/json'
        ];
        
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $this->baseUrl . '/payment-requests');
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($paymentData));
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        
        $response = curl_exec($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);
        
        if ($httpCode === 401) {
            throw new Exception('Invalid API key - please check your credentials');
        }
        
        return json_decode($response, true);
    }
}
?>
```

### Python Example

```python theme={null}
import requests
import os

class CaiboClient:
    def __init__(self, api_key=None):
        self.api_key = api_key or os.getenv('CAIBO_API_KEY')
        self.base_url = 'https://apay.caibo.digital'
        self.headers = {
            'X-API-Key': self.api_key,
            'Content-Type': 'application/json'
        }
    
    def create_payment(self, payment_data):
        response = requests.post(
            f'{self.base_url}/payment-requests',
            json=payment_data,
            headers=self.headers
        )
        
        if response.status_code == 401:
            raise Exception('Invalid API key - please check your credentials')
        
        response.raise_for_status()
        return response.json()

# Usage
client = CaiboClient()
payment = client.create_payment({
    'amount': 100.00,
    'currency': 'EUR',
    'reference': 'ORDER-12345'
})
```

## Troubleshooting

### Common Issues

#### API Key Not Working

1. **Verify key format** - Should start with `caibo_live_sk_` or `caibo_test_sk_`
2. **Check environment** - Ensure using correct key for environment
3. **Confirm regeneration** - Verify key hasn't been regenerated recently

#### Control Panel Access Issues

1. **Password reset** - Use forgot password if needed
2. **Account status** - Verify account is active and in good standing
3. **Browser issues** - Clear cache and cookies, try different browser

#### Integration Problems

1. **Header format** - Ensure `X-API-Key` header is correctly formatted
2. **HTTPS required** - All requests must use HTTPS
3. **Content-Type** - Include `application/json` for POST requests

### Getting Help

If you encounter authentication issues:

1. **Check API Status** - Visit status.caibo.digital for service status
2. **Review Logs** - Check your application logs for detailed error messages
3. **Contact Support** - Reach out to [support@caibo.digital](mailto:support@caibo.digital) with:
   * Your merchant ID
   * Error messages and timestamps
   * Steps to reproduce the issue

## Next Steps

<Card title="Payment Requests" icon="credit-card" href="/ipg/payment-requests/payment-request">
  Create your first payment request
</Card>

<Card title="Webhooks Setup" icon="webhook" href="/ipg/callbacks">
  Configure real-time payment notifications
</Card>

<Card title="API Reference" icon="code" href="/api-ref">
  Explore the complete API documentation
</Card>

<Card title="Control Panel Guide" icon="settings" href="/cpanel/getting-started">
  Learn more about the merchant control panel
</Card>
