# Bitbull CMS — License Verification API

**Base URL:** `https://cms.bitbulltech.com/verify/`  
**Method:** `POST` only  
**Content-Type:** `application/json` (form-urlencoded also accepted)

---

## Request Body

```json
{
  "license_key": "ABCD-1234-EFGH-5678",
  "machine_id": "UNIQUE-MACHINE-ID-12345"
}
```

| Field | Required | Notes |
|-------|----------|-------|
| `license_key` | Yes | 16 alphanumeric characters; dashes optional (`ABCD-1234-EFGH-5678` = `ABCD1234EFGH5678`) |
| `machine_id` | Yes* | Unique ID for this PC/installation |
| `mac_address` | Yes* | Alternative to `machine_id` — use one or the other |

\* At least one of `machine_id` or `mac_address` is required.

### Example cURL

```bash
curl -X POST https://cms.bitbulltech.com/verify/ \
  -H "Content-Type: application/json" \
  -d '{"license_key":"ABCD-1234-EFGH-5678","machine_id":"UNIQUE-MACHINE-ID-12345"}'
```

---

## Success Response

**HTTP `200`**

```json
{
  "status": "success",
  "message": "License activated",
  "expiry_date": "2027-12-31"
}
```

| Field | Type | Description |
|-------|------|-------------|
| `status` | string | Always `"success"` |
| `message` | string | Always `"License activated"` |
| `expiry_date` | string | License expiry in `YYYY-MM-DD` format |

**Desktop app logic:** Treat `status === "success"` as a valid license. Store `expiry_date` locally and re-check before it passes.

---

## Failure Responses

All failures return `"status": "error"`. Check both the HTTP status code and the `message` field.

### 1. Missing required fields

**HTTP `400`**

```json
{
  "status": "error",
  "message": "license_key and machine_id (or mac_address) are required"
}
```

### 2. Invalid license key format

**HTTP `400`**

```json
{
  "status": "error",
  "message": "Invalid license key format"
}
```

Triggered when the key is not exactly 16 alphanumeric characters after removing dashes and spaces.

### 3. License key not found

**HTTP `403`**

```json
{
  "status": "error",
  "message": "Invalid license key"
}
```

### 4. License already bound to another machine

**HTTP `403`**

```json
{
  "status": "error",
  "message": "License key does not match this system"
}
```

Occurs when the key was already activated on a different `machine_id` / `mac_address`.

### 5. License deactivated

**HTTP `403`**

```json
{
  "status": "error",
  "message": "License is not active"
}
```

### 6. License expired

**HTTP `403`**

```json
{
  "status": "error",
  "message": "License has expired",
  "expiry_date": "2025-01-01"
}
```

Note: `expiry_date` is included only on expiry failures.

### 7. Wrong HTTP method (GET, etc.)

**HTTP `405`**

```json
{
  "status": "error",
  "message": "Method not allowed"
}
```

### 8. Server / database error

**HTTP `500`**

```json
{
  "status": "error",
  "message": "Database connection failed"
}
```

---

## Quick Reference

| HTTP Code | `status` | `message` | When |
|-----------|----------|-----------|------|
| `200` | `success` | `License activated` | Valid license, machine matches |
| `400` | `error` | `license_key and machine_id (or mac_address) are required` | Missing fields |
| `400` | `error` | `Invalid license key format` | Key not 16 characters |
| `403` | `error` | `Invalid license key` | Key not in database |
| `403` | `error` | `License key does not match this system` | Used on another PC |
| `403` | `error` | `License is not active` | Status not Active |
| `403` | `error` | `License has expired` | Past expiry date |
| `405` | `error` | `Method not allowed` | Not POST |
| `500` | `error` | `Database connection failed` | Server issue |

---

## Recommended Desktop App Flow

```
1. Collect machine_id (hardware UUID, MAC hash, etc.) — keep it stable per PC
2. POST to https://cms.bitbulltech.com/verify/
3. If HTTP 200 AND status == "success" → allow app, save expiry_date
4. If status == "error" → show message to user
5. Re-verify on app startup (or daily) using the same machine_id
```

**First activation:** If `system_id` is empty in the database, the server binds the license to the first `machine_id` that calls.

**Re-activation:** The same `machine_id` on the same PC always succeeds (until expired or deactivated).

---

## Sample Responses for Testing

**Success:**

```json
{"status":"success","message":"License activated","expiry_date":"2027-12-31"}
```

**Wrong machine:**

```json
{"status":"error","message":"License key does not match this system"}
```

**Expired:**

```json
{"status":"error","message":"License has expired","expiry_date":"2025-01-01"}
```
