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

# Integrating Avalex License Validation into Your App

> Learn how to embed Avalex license validation in your software. Covers the validation flow, best practices, and links to language-specific examples.

Integrating Avalex into your application means embedding a call to the `POST /licenses/validate` endpoint directly in your startup logic — and optionally on a periodic heartbeat. Your app generates a stable hardware identifier (HWID), sends it alongside the license and product IDs, and gates the rest of the application flow on the `valid` field in the response. This page explains the integration pattern, links to language-specific examples, and outlines best practices for security and offline resilience.

## Integration Flow

The following steps describe the standard Avalex validation lifecycle from application launch to either successful startup or graceful degradation.

<Steps>
  <Step title="Generate a stable HWID at startup">
    Derive a hardware identifier from immutable system properties (machine UUID, CPU info, etc.) and hash them with SHA-256. This value must remain consistent across reboots so that a valid activation is not inadvertently revoked by a transient system change.
  </Step>

  <Step title="Call POST /licenses/validate">
    Send a JSON request body containing the `licenseId` supplied by your user, your application's `productId`, and the computed `hwid` to the validation endpoint.

    ```http theme={null}
    POST /licenses/validate
    Content-Type: application/json

    {
      "licenseId": "LIC-8829-X19",
      "productId": "prod_enterprise_2026",
      "hwid": "A3F1C9B2D4E67890A3F1C9B2D4E67890"
    }
    ```
  </Step>

  <Step title="If {&#x22;valid&#x22;: true} — proceed with app launch">
    A `200 OK` response with `"valid": true` confirms the license is active and bound to the current machine. Store the current timestamp locally so you can support an offline grace period for future launches.
  </Step>

  <Step title="If {&#x22;valid&#x22;: false} or an error — show an error or fall back to cached grace period">
    A `"valid": false` result, a `429 Too Many Requests`, or a network failure should not immediately lock out your user. Check your locally cached timestamp first. If the last successful validation falls within your configured grace window (24–72 hours), allow the session to continue. Otherwise, present a clear error message explaining that the license could not be verified.
  </Step>
</Steps>

## Language Guides

Choose the guide that matches your application's language or runtime. Each guide includes a complete working example with HWID generation, request construction, and error handling.

<CardGroup cols={3}>
  <Card title="Java" icon="java" href="/integration/java">
    Native `java.net.http.HttpClient` validation and SHA-256 HWID generation for Java 11+ applications.
  </Card>

  <Card title="Python" icon="python" href="/integration/python">
    Cross-platform HWID generation and `requests`-based validation for Python desktop and server applications.
  </Card>

  <Card title="C#" icon="square-c" href="/integration/csharp">
    Async `HttpClient` integration for .NET Core, WPF, and WinForms applications.
  </Card>

  <Card title="TypeScript" icon="js" href="/integration/typescript">
    Node.js and Electron validation using the `crypto` and `os` modules with full TypeScript typings.
  </Card>

  <Card title="Rust" icon="rust" href="/integration/rust">
    Typed `reqwest` + `serde` integration with async/await for compiled Rust binaries.
  </Card>
</CardGroup>

## Best Practices

Following these guidelines will make your integration more resilient, secure, and respectful of the API rate limits.

<Warning>
  The Avalex validation endpoint enforces a rate limit of **30 requests per minute per IP address**. Exceeding this limit returns an HTTP `429 Too Many Requests` response. Never poll the endpoint on a tight loop — always use the heartbeat frequencies described below.
</Warning>

1. **HWID generation** — Combine at least two immutable hardware sources (e.g., machine UUID and CPU model) before hashing. Using a single volatile source (like a username) risks generating a new HWID after routine system changes, which will cause valid licenses to fail binding checks. Always apply SHA-256 and truncate or encode the result consistently.
2. **Offline caching** — After every successful `"valid": true` response, persist the current UTC timestamp to local storage (encrypted where possible). On subsequent launches, if the validation endpoint is unreachable or returns an error, compare the stored timestamp against your grace window. A grace period of **24–72 hours** balances user experience against licensing security.
3. **Heartbeat frequency** — Always validate at application launch. If your application runs for extended periods (e.g., a background service or long-running desktop app), schedule a revalidation every **6–24 hours**. Never issue validation requests more frequently than necessary — aggressive polling wastes quota and risks hitting the rate limit.
4. **Security** — Always use **HTTPS** when calling the Avalex API in production environments; the `http://localhost:8080` base URL is for local development only. In compiled binaries, obfuscate your license-check routines (string constants, call sites, and response-handling logic) to raise the cost of bypassing validation. Avoid logging full license IDs or HWIDs to plaintext files.
