> For the complete documentation index, see [llms.txt](https://easyauth.papelship.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://easyauth.papelship.com/documentation/main-functions/validate-key.md).

# Validate Key

Validates a user license key against the authentication server and establishes an authorized session.

{% hint style="info" %}
A secure connection must be established by calling `QP_Connect(ctx)` (or `easyauth::network_connect()`) before validating a license key.
{% endhint %}

## Function Signatures

{% tabs %}
{% tab title="C Flat API" %}

```cpp
char* QP_Authenticate(QPCTX ctx, const char* license_key, const char* api_key);
```

{% endtab %}

{% tab title="C++ Object API" %}

```cpp
easyauth::auth_result easyauth::authenticate(const std::string& key, const std::string& api_key = "");
```

{% endtab %}
{% endtabs %}

## Parameters

| Parameter     | Type                          | Description                                                          | Required |
| ------------- | ----------------------------- | -------------------------------------------------------------------- | -------- |
| `ctx`         | `QPCTX`                       | Active security context pointer.                                     | Yes      |
| `license_key` | `const char*` / `std::string` | License key provided by user (e.g. `EASY-AUTH-2026-KEY1`).           | Yes      |
| `api_key`     | `const char*` / `std::string` | Product API key (optional if already configured via `QP_SetConfig`). | Optional |

## Return Values

{% tabs %}
{% tab title="C Flat API Return" %}
Returns a dynamically allocated JSON string (`char*`). Returns `nullptr` if communication fails entirely.

```json
{
  "success": true,
  "error_code": 0,
  "error_name": "OK",
  "message": "Key successfully validated.",
  "expire_date": "2027-08-23 23:59:59"
}
```

{% hint style="warning" %}
**Memory Management**: You **must** release the returned string pointer by calling `QP_FreeString(authJson)` to prevent memory leaks in your application.
{% endhint %}
{% endtab %}

{% tab title="C++ Struct Return" %}
Returns an `easyauth::auth_result` struct:

```cpp
struct auth_result {
    bool success;            // true if key is valid and active
    int error_code;          // 0 on success, error code on failure
    std::string error_name;  // Short machine-readable error (e.g. "KEY_EXPIRED")
    std::string message;     // Detailed human-readable description
    std::string expire_date; // Expiration timestamp string
};
```

{% endtab %}
{% endtabs %}

## Code Examples

### C Flat API Example

```cpp
#include <iostream>
#include "qPapelEasyAuth.h"

void ValidateLicense(QPCTX ctx, const std::string& key) {
    std::cout << "[*] Validating license key: " << key << "...\n";
    
    char* resultJson = QP_Authenticate(ctx, key.c_str(), nullptr);
    if (resultJson != nullptr) {
        std::cout << "[+] Server Response:\n" << resultJson << "\n";
        
        // Parse or check for success in JSON
        if (std::string(resultJson).find("\"success\":true") != std::string::npos) {
            std::cout << "[+] License is VALID!\n";
        } else {
            std::cerr << "[-] License is INVALID!\n";
        }
        
        // ALWAYS free dynamically allocated string
        QP_FreeString(resultJson);
    } else {
        char* err = QP_GetLastStatus(ctx);
        std::cerr << "[-] Network error: " << (err ? err : "Unknown") << "\n";
        if (err) QP_FreeString(err);
    }
}
```

### Modern C++ Example

```cpp
#include <iostream>
#include "qPapelEasyAuth.h"

void ValidateLicenseCpp(const std::string& key) {
    easyauth::auth_result res = easyauth::authenticate(key);
    
    if (res.success) {
        std::cout << "[+] Authentication Successful!\n";
        std::cout << "[+] License Expires On: " << res.expire_date << "\n";
    } else {
        std::cerr << "[-] Auth Failed: " << res.error_name << " (" << res.message << ")\n";
    }
}
```

## Server Validation Rules

When `QP_Authenticate` is called, the server performs the following checks:

{% stepper %}
{% step %}

### Database Existence

Verifies that the key exists under the specified `api_key` product.
{% endstep %}

{% step %}

### Key Expiration

Checks if current server timestamp exceeds `expires_at`.
{% endstep %}

{% step %}

### HWID Binding

Compares hardware telemetry against registered device fingerprint.
{% endstep %}

{% step %}

### Device Limit (Multi-device)

Checks if active concurrent bindings exceed `max_devices`.
{% endstep %}

{% step %}

### Anti-Tamper Signature

Verifies client `.text` CRC32 and cryptographic sequence number.
{% endstep %}
{% endstepper %}
