# LACE (Love Alignment & Compatibility Engine) — API Documentation

This API enables partners and clients to generate Human Design compatibility reports, search locations, and fetch Human Design birth chart data.

---

## Authentication

All `/api/*` endpoints require a valid API key. You can authenticate using any of the following methods:

1. **HTTP Header (Recommended)**
   ```http
   X-API-Key: <your_api_key_here>
   ```

2. **Authorization Header (Bearer Token)**
   ```http
   Authorization: Bearer <your_api_key_here>
   ```

3. **Query Parameter**
   ```
   GET /api/locations?query=London&api_key=<your_api_key_here>
   ```

---

## Endpoints

### 1. Generate Compatibility Report
Generates detailed compatibility analyses, scores, and chart SVGs for two individuals.

* **URL**: `/api/compatibility-report`
* **Method**: `POST`
* **Headers**: 
  - `Content-Type: application/json`
  - `X-API-Key: <your_api_key_here>`
* **Payload Format**:
  ```json
  {
    "personA": {
      "name": "Irene",
      "date": "1989-12-21T09:58:00",
      "timezone": "America/Guatemala"
    },
    "personB": {
      "name": "JP",
      "date": "1985-04-13T11:59:00",
      "timezone": "America/Los_Angeles"
    }
  }
  ```
  *(Note: The date format should be `YYYY-MM-DDTHH:MM:SS` or `YYYY-MM-DD HH:MM`)*

* **Alternative Payload Format (with City Fallback)**:
  If a partner's application has not yet collected a timezone string, they can send `city` instead. The server will automatically search its local database of major global cities to resolve it.
  ```json
  {
    "personA": {
      "name": "Irene",
      "date": "1989-12-21T09:58:00",
      "city": "Guatemala City, Guatemala"
    },
    "personB": {
      "name": "JP",
      "date": "1985-04-13T11:59:00",
      "city": "Los Angeles, USA"
    }
  }
  ```
  *(Warning: If the city cannot be resolved and no timezone is sent, the server returns `400 Bad Request` rather than silently defaulting to `UTC`).*

* **Response (JSON)**:
  Returns calculated overall compatibility scores, charts, and SVG graphics.
  ```json
  {
    "chartA": { ... },
    "chartB": { ... },
    "report": {
      "overall": 82.5,
      "chemistry": { "score": 88, "label": "Strong Attraction" },
      "compatibility": { "score": 75 },
      "alignment": { "score": 85 }
    },
    "chartA_img": "<svg>...</svg>",
    "chartB_img": "<svg>...</svg>"
  }
  ```

#### **Code Integration Examples**

**JavaScript (Fetch):**
```javascript
const apiKey = 'YOUR_API_KEY';
const baseUrl = 'http://localhost:8080'; // Replace with production URL

async function getCompatibilityReport() {
  const payload = {
    personA: {
      name: "Irene",
      date: "1989-12-21 09:58",
      timezone: "America/Guatemala"
    },
    personB: {
      name: "JP",
      date: "1985-04-13 11:59",
      timezone: "America/Los_Angeles"
    }
  };

  try {
    const response = await fetch(`${baseUrl}/api/compatibility-report`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'X-API-Key': apiKey
      },
      body: JSON.stringify(payload)
    });

    if (!response.ok) {
      const errorData = await response.json();
      throw new Error(`API Error: ${errorData.error || response.statusText}`);
    }

    const data = await response.json();
    console.log("Compatibility Score:", data.report.overall);
    return data;
  } catch (error) {
    console.error("Failed to fetch compatibility report:", error);
  }
}
```

**Python (Requests):**
```python
import requests

api_key = "YOUR_API_KEY"
base_url = "http://localhost:8080"  # Replace with production URL

payload = {
    "personA": {
        "name": "Irene",
        "date": "1989-12-21 09:58",
        "timezone": "America/Guatemala"
    },
    "personB": {
        "name": "JP",
        "date": "1985-04-13 11:59",
        "timezone": "America/Los_Angeles"
    }
}

headers = {
    "Content-Type": "application/json",
    "X-API-Key": api_key
}

response = requests.post(f"{base_url}/api/compatibility-report", json=payload, headers=headers)
if response.status_code == 200:
    data = response.json()
    print("Compatibility Score:", data["report"]["overall"])
else:
    print(f"Error ({response.status_code}):", response.json().get("error"))
```

**cURL:**
```bash
curl -X POST http://localhost:8080/api/compatibility-report \
  -H "Content-Type: application/json" \
  -H "X-API-Key: YOUR_API_KEY" \
  -d '{
    "personA": {
      "name": "Irene",
      "date": "1989-12-21 09:58",
      "timezone": "America/Guatemala"
    },
    "personB": {
      "name": "JP",
      "date": "1985-04-13 11:59",
      "timezone": "America/Los_Angeles"
    }
  }'
```

---

### 2. Search Locations
Queries major global cities and retrieves matching names and their valid IANA timezones.

* **URL**: `/api/locations`
* **Method**: `GET`
* **Query Parameters**:
  - `query`: Minimum 2-character search term (e.g. `New York`)
* **Response (JSON)**:
  ```json
  [
    {
      "value": "New York, USA",
      "timezone": "America/New_York",
      "label": "New York, USA"
    }
  ]
  ```

#### **Code Integration Examples**

**JavaScript (Fetch):**
```javascript
const apiKey = 'YOUR_API_KEY';
const baseUrl = 'http://localhost:8080';

async function searchLocations(query) {
  try {
    const response = await fetch(`${baseUrl}/api/locations?query=${encodeURIComponent(query)}`, {
      method: 'GET',
      headers: {
        'X-API-Key': apiKey
      }
    });
    if (!response.ok) throw new Error("Search failed");
    return await response.json();
  } catch (error) {
    console.error("Location search error:", error);
  }
}
```

**Python (Requests):**
```python
import requests

api_key = "YOUR_API_KEY"
base_url = "http://localhost:8080"

response = requests.get(
    f"{base_url}/api/locations",
    params={"query": "London"},
    headers={"X-API-Key": api_key}
)
if response.status_code == 200:
    cities = response.json()
    print("Found cities:", cities)
```

**cURL:**
```bash
curl -X GET "http://localhost:8080/api/locations?query=London" \
  -H "X-API-Key: YOUR_API_KEY"
```

---

### 3. Fetch Human Design Birth Chart Data
Retrieves calculated birth chart data from coordinates/time.

* **URL**: `/api/hd-data`
* **Method**: `GET`
* **Query Parameters**:
  - `date`: `YYYY-MM-DDTHH:MM` local time
  - `timezone`: Valid IANA timezone (e.g. `Europe/London`)
* **Response (JSON)**:
  Returns active gates, unconscious/conscious centers, definition details, and profiles.

#### **Code Integration Examples**

**JavaScript (Fetch):**
```javascript
const apiKey = 'YOUR_API_KEY';
const baseUrl = 'http://localhost:8080';

async function fetchHdData(dateString, timezoneString) {
  const url = `${baseUrl}/api/hd-data?date=${encodeURIComponent(dateString)}&timezone=${encodeURIComponent(timezoneString)}`;
  try {
    const response = await fetch(url, {
      method: 'GET',
      headers: {
        'X-API-Key': apiKey
      }
    });
    if (!response.ok) throw new Error("Failed to fetch HD data");
    return await response.json();
  } catch (error) {
    console.error("HD Data error:", error);
  }
}
```

**Python (Requests):**
```python
import requests

api_key = "YOUR_API_KEY"
base_url = "http://localhost:8080"

params = {
    "date": "1989-12-21T09:58",
    "timezone": "America/Guatemala"
}
response = requests.get(
    f"{base_url}/api/hd-data",
    params=params,
    headers={"X-API-Key": api_key}
)
if response.status_code == 200:
    hd_data = response.json()
    print("Gates:", hd_data.get("Gates"))
```

**cURL:**
```bash
curl -X GET "http://localhost:8080/api/hd-data?date=1989-12-21T09:58&timezone=America/Guatemala" \
  -H "X-API-Key: YOUR_API_KEY"
```

---

## Response Status Codes & Rate Limiting

The API uses standard HTTP response codes to indicate success or failure:

| Status Code | Description | Reason |
| :--- | :--- | :--- |
| **200 OK** | Request succeeded. | The operation completed successfully. |
| **400 Bad Request** | Request failed validation. | Missing parameter, date parsing error, or timezone could not be resolved from city name. |
| **401 Unauthorized** | Authentication failed. | API Key is missing or invalid. |
| **403 Forbidden** | Request blocked. | The API Key has been **revoked** or admin endpoint is accessed from non-localhost. |
| **429 Too Many Requests** | Rate limit exceeded. | Request count exceeded the designated Requests Per Minute (RPM) threshold. |

---

## Developer / Partner Management Dashboard

For administrators running the LACE (Love Alignment & Compatibility Engine) server locally, a dashboard is available at:
* **URL**: `http://localhost:8080/admin` *(Restricted to local connections)*

From this dashboard, you can:
- **View active key metrics**: Total keys, active connections, revoked keys, and API logs.
- **Generate API Keys**: Input partner names and set a rate limit (Requests Per Minute).
- **Revoke or Reactivate Keys**: Toggle the active status of any generated key in real-time.
- **Inspect usage logs**: View timestamps, status codes, IPs, methods, and endpoints for all requests.
