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

# Keys

> Generate, manage, ban, and reset script keys for your users.

# Key Management

Leaf7 uses a two-stage key system:

1. **Buyer Keys** — Unredeemed keys you generate and distribute to customers
2. **Script Keys (Active Keys)** — Keys that have been redeemed and are bound to a user's Discord ID and HWID

<Info>
  When a user redeems a buyer key (via the Discord bot or by executing with the key), a **Script Key** is created automatically. The buyer key is marked as redeemed, and the user's Discord ID and HWID are linked.
</Info>

<Note>
  If there's **no HWID** assigned to a key, it will automatically get assigned when the user first executes the script with `script_key = "key here"` on top of their loader.
</Note>

***

## Generate buyer keys

`POST` `/api/vendor/keys/buyer`

Generate one or more unredeemed buyer keys for distribution.

#### Headers

| Name            | Type   | Required | Description           |
| --------------- | ------ | -------- | --------------------- |
| `Authorization` | String | ✅        | `Bearer YOUR_API_KEY` |

#### Request Body

| Name          | Type    | Required | Description                                                 |
| ------------- | ------- | -------- | ----------------------------------------------------------- |
| `project_id`  | String  | ✅        | Project to generate keys for                                |
| `amount`      | Integer | ❌        | Number of keys to generate (default: `1`)                   |
| `key_days`    | Integer | ❌        | Days until key expires **after redemption** (default: `30`) |
| `key_hours`   | Integer | ❌        | Additional hours to add to expiry                           |
| `key_minutes` | Integer | ❌        | Additional minutes to add to expiry                         |

<Tip>
  Set `key_days` to `0` with `key_hours` and `key_minutes` also at `0` to create **lifetime keys** that never expire.
</Tip>

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://auth.leaf7.fun/api/vendor/keys/buyer \
    -H "Authorization: Bearer YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "project_id": "a1b2c3d4-...",
      "amount": 10,
      "key_days": 30
    }'
  ```

  ```python Python theme={null}
  resp = requests.post(
      "https://auth.leaf7.fun/api/vendor/keys/buyer",
      headers={"Authorization": "Bearer YOUR_API_KEY"},
      json={
          "project_id": "a1b2c3d4-...",
          "amount": 10,
          "key_days": 30
      }
  )
  keys = resp.json()
  for key in keys:
      print(key["key_id"])  # Distribute these to your customers
  ```
</CodeGroup>

<Tabs>
  <Tab title="200 OK">
    ```json theme={null}
    [
        {
            "key_id": "XkJ9a2bR4mN7pQ3w...",
            "project_id": "a1b2c3d4-...",
            "created_at": "2026-05-03T12:00:00",
            "redeemed": false,
            "discord_id": null,
            "key_days": 30,
            "key_hours": 0,
            "key_minutes": 0
        }
    ]
    ```
  </Tab>

  <Tab title="403 Forbidden">
    ```json theme={null}
    { "detail": "Discord account must be linked before you can generate buyer keys." }
    ```
  </Tab>

  <Tab title="404 Not Found">
    ```json theme={null}
    { "detail": "Project not found" }
    ```
  </Tab>
</Tabs>

***

## Get buyer keys

`GET` `/api/vendor/keys/buyer`

Fetch all buyer keys, optionally filtered by project.

#### Query Parameters

| Name         | Type   | Required | Description                |
| ------------ | ------ | -------- | -------------------------- |
| `project_id` | String | ❌        | Filter by specific project |

<Tabs>
  <Tab title="200 OK">
    ```json theme={null}
    [
        {
            "key_id": "XkJ9a2bR4mN7pQ3w...",
            "project_id": "a1b2c3d4-...",
            "created_at": "2026-05-03T12:00:00",
            "redeemed": false,
            "discord_id": null,
            "key_days": 30,
            "key_hours": 0,
            "key_minutes": 0
        },
        {
            "key_id": "Ym8n3pLkF7qR2sX...",
            "project_id": "a1b2c3d4-...",
            "created_at": "2026-05-03T12:00:00",
            "redeemed": true,
            "discord_id": "123456789012345678",
            "key_days": 30,
            "key_hours": 0,
            "key_minutes": 0
        }
    ]
    ```
  </Tab>
</Tabs>

***

## Delete a buyer key

`DELETE` `/api/vendor/keys/buyer/{key_id}`

Remove an unredeemed buyer key. **Redeemed keys cannot be deleted** — ban the associated active key instead.

#### Path Parameters

| Name     | Type   | Required | Description             |
| -------- | ------ | -------- | ----------------------- |
| `key_id` | String | ✅        | The buyer key to delete |

<Tabs>
  <Tab title="200 OK">
    ```json theme={null}
    { "status": "success" }
    ```
  </Tab>

  <Tab title="400 Bad Request">
    ```json theme={null}
    { "detail": "Cannot delete a redeemed key" }
    ```
  </Tab>

  <Tab title="404 Not Found">
    ```json theme={null}
    { "detail": "Key not found" }
    ```
  </Tab>
</Tabs>

***

## Get active keys

`GET` `/api/vendor/keys/active`

Fetch all redeemed (active) script keys. These are real user sessions with linked Discord IDs and HWIDs.

#### Query Parameters

| Name         | Type   | Required | Description       |
| ------------ | ------ | -------- | ----------------- |
| `project_id` | String | ❌        | Filter by project |

<Tabs>
  <Tab title="200 OK">
    ```json theme={null}
    [
        {
            "key_id": "XkJ9a2bR4mN7pQ3w...",
            "project_id": "a1b2c3d4-...",
            "discord_id": "123456789012345678",
            "hwid": "a8f3b2c1d0e9...",
            "hwid_resets": 2,
            "total_executions": 47,
            "last_execution": "2026-05-03T15:30:00",
            "last_reset": "2026-05-01T10:00:00",
            "redeemed_at": "2026-04-15T08:00:00",
            "expires_at": "2026-05-15T08:00:00",
            "banned": false
        }
    ]
    ```

    <Note>
      `expires_at` of `null` means the key is a **lifetime** key.
    </Note>
  </Tab>
</Tabs>

***

## Ban a key

`POST` `/api/vendor/keys/active/{key_id}/ban`

Ban a user from executing your script. Their HWID is blocked immediately.

#### Path Parameters

| Name     | Type   | Required | Description                  |
| -------- | ------ | -------- | ---------------------------- |
| `key_id` | String | ✅        | The active script key to ban |

<Tabs>
  <Tab title="200 OK">
    ```json theme={null}
    { "status": "success" }
    ```
  </Tab>

  <Tab title="404 Not Found">
    ```json theme={null}
    { "detail": "Key not found" }
    ```
  </Tab>
</Tabs>

***

## Unban a key

`POST` `/api/vendor/keys/active/{key_id}/unban`

Restore access for a previously banned key.

#### Path Parameters

| Name     | Type   | Required | Description                    |
| -------- | ------ | -------- | ------------------------------ |
| `key_id` | String | ✅        | The active script key to unban |

<Tabs>
  <Tab title="200 OK">
    ```json theme={null}
    { "status": "success" }
    ```
  </Tab>
</Tabs>

***

## Reset HWID

`POST` `/api/vendor/keys/active/{key_id}/reset_hwid`

Clear the HWID lock on a key, allowing the user to execute from a new device. The HWID will be re-assigned on next execution.

#### Path Parameters

| Name     | Type   | Required | Description           |
| -------- | ------ | -------- | --------------------- |
| `key_id` | String | ✅        | The active script key |

<Tabs>
  <Tab title="200 OK">
    ```json theme={null}
    { "status": "success" }
    ```
  </Tab>

  <Tab title="404 Not Found">
    ```json theme={null}
    { "detail": "Key not found" }
    ```
  </Tab>
</Tabs>

<Info>
  This endpoint **bypasses** the cooldown timer. The `hwid_reset_cooldown` setting on the project only applies to self-service resets via the Discord bot.
</Info>

***

## Update HWID

`PATCH` `/api/vendor/keys/active/{key_id}/hwid`

Manually set or clear the HWID on a key.

#### Path Parameters

| Name     | Type   | Required | Description           |
| -------- | ------ | -------- | --------------------- |
| `key_id` | String | ✅        | The active script key |

#### Request Body

| Name       | Type   | Required | Description                            |
| ---------- | ------ | -------- | -------------------------------------- |
| `new_hwid` | String | ❌        | New HWID to set. Pass `null` to clear. |

<Tabs>
  <Tab title="200 OK">
    ```json theme={null}
    { "status": "success", "hwid": "new-hwid-value" }
    ```
  </Tab>
</Tabs>
