# Pool Chemistry API
> Swimming-pool water-chemistry maths as an API, computed locally and deterministically — the dosing and water-balance numbers a pool service tech or owner runs at every visit. The chlorine endpoint works out how much of a product to add to raise free chlorine from the current to a target ppm in a given volume: dose (g) = Δppm × litres / 1000 ÷ the product's available-chlorine fraction, with built-in strengths for liquid chlorine (12.5 %), household bleach (6 %), cal-hypo (65 %), dichlor (56 %) and trichlor (90 %), or your own — raising 50,000 litres by 2 ppm needs 800 g of liquid chlorine or 154 g of cal-hypo. The lsi endpoint computes the Langelier Saturation Index, LSI = pH + temperature factor + calcium factor + alkalinity factor − 12.1, the standard measure of whether water is corrosive (below −0.3, eating plaster and metal), balanced (−0.3 to +0.3) or scaling (above +0.3), with a cyanuric-acid correction to the carbonate alkalinity. Everything is computed locally and deterministically, so it is instant and private. Ideal for pool-service, spa, water-treatment and home-maintenance app developers, dosing and water-balance tools, and pool-care education. Pure local computation — no key, no third-party service, instant. Metric: litres, ppm (mg/L), °C. Live, nothing stored. 2 compute endpoints. Always confirm with a test kit — this is an aid, not a substitute. For pool water volume use a pool-geometry API.

## Authentication
All requests require your oanor API key in the `x-oanor-key` header. Get one at https://www.oanor.com/developer/keys.

```bash
curl -H "x-oanor-key: oanor_live_…" "https://api.oanor.com/poolchem-api/..."
```

## Pricing
- **Free** (Free) — 5,450 calls/Mo, 2 req/s
- **Starter** ($4/Mo) — 51,000 calls/Mo, 6 req/s
- **Pro** ($12/Mo) — 209,000 calls/Mo, 15 req/s
- **Mega** ($36/Mo) — 1,320,000 calls/Mo, 40 req/s

## Endpoints

### PoolChem

#### `GET /v1/chlorine` — Chlorine dose to target ppm

**Parameters:**
- `volume` (query, required, string) — Pool volume (litres) Example: `50000`
- `target_ppm` (query, required, string) — Target free chlorine (ppm) Example: `3`
- `current_ppm` (query, optional, string) — Current free chlorine (ppm) Example: `1`
- `product` (query, optional, string) — liquid, bleach, cal-hypo, dichlor, trichlor Example: `liquid`
- `strength_percent` (query, optional, string) — Custom available-chlorine %

**Example:**
```bash
curl -H "x-oanor-key: $KEY" \
  "https://api.oanor.com/poolchem-api/v1/chlorine?volume=50000&target_ppm=3&current_ppm=1&product=liquid"
```

**Response:**
```json
{
    "data": {
        "note": "Dose (g) = Δppm × volume(L) / 1000 ÷ available-chlorine fraction. ppm is mg/L; for a liquid product grams ≈ millilitres (density ≈ 1).",
        "inputs": {
            "volume": 50000,
            "product": "liquid",
            "target_ppm": 3,
            "current_ppm": 1,
            "strength_percent": 12.5
        },
        "delta_ppm": 2,
        "dose_grams": 800,
        "available_chlorine_grams": 100,
        "dose_milliliters_if_liquid": 800
    },
    "meta": {
        "timestamp": "2026-06-05T21:48:45.458Z",
        "request_id": "61309f29-3003-4b32-98de-0ba8bbc1011f"
    },
    "status": "ok",
    "message": "Chlorine dose",
    "success": true
}
```

#### `GET /v1/lsi` — Langelier Saturation Index

**Parameters:**
- `ph` (query, required, string) — pH Example: `7.5`
- `calcium_hardness` (query, required, string) — Calcium hardness (ppm) Example: `300`
- `total_alkalinity` (query, required, string) — Total alkalinity (ppm) Example: `100`
- `temperature` (query, optional, string) — Water temperature (°C, default 26) Example: `29`
- `cyanuric_acid` (query, optional, string) — Cyanuric acid (ppm)

**Example:**
```bash
curl -H "x-oanor-key: $KEY" \
  "https://api.oanor.com/poolchem-api/v1/lsi?ph=7.5&calcium_hardness=300&total_alkalinity=100&temperature=29"
```

**Response:**
```json
{
    "data": {
        "lsi": 0.177,
        "note": "LSI = pH + TF + CF + AF − 12.1. Between −0.3 and +0.3 is balanced; below corrodes plaster and metal, above scales. TF from temperature, CF = log10(Ca)−0.4, AF = log10(carbonate alkalinity).",
        "inputs": {
            "ph": 7.5,
            "temperature": 29,
            "cyanuric_acid": 0,
            "calcium_hardness": 300,
            "total_alkalinity": 100
        },
        "balance": "balanced",
        "calcium_factor": 2.0771,
        "alkalinity_factor": 2,
        "temperature_factor": 0.7,
        "carbonate_alkalinity": 100
    },
    "meta": {
        "timestamp": "2026-06-05T21:48:45.534Z",
        "request_id": "e9a0d079-abbc-4ac9-8884-2defe4923d6f"
    },
    "status": "ok",
    "message": "Langelier index",
    "success": true
}
```

### Meta

#### `GET /v1/meta` — Spec

**Example:**
```bash
curl -H "x-oanor-key: $KEY" \
  "https://api.oanor.com/poolchem-api/v1/meta"
```

**Response:**
```json
{
    "data": {
        "notes": "Volume in litres, ppm as mg/L, temperature in °C. Product strengths default to common values (liquid 12.5%, cal-hypo 65%, …) or pass strength_percent. Always confirm with a test kit — this is an aid, not a substitute.",
        "service": "poolchem-api",
        "endpoints": {
            "GET /v1/lsi": "Langelier Saturation Index and whether the water is corrosive, balanced or scaling.",
            "GET /v1/meta": "This document.",
            "GET /v1/chlorine": "Dose of a chlorine product to reach a target free-chlorine ppm."
        },
        "description": "Swimming-pool water chemistry: chlorine dosing and the Langelier Saturation Index (water balance)."
    },
    "meta": {
        "timestamp": "2026-06-05T21:48:45.630Z",
        "request_id": "e371e2e4-c048-4565-a0f9-aa22346eb33a"
    },
    "status": "ok",
    "message": "Meta",
    "success": true
}
```


---
Marketplace page: https://www.oanor.com/api/poolchem-api
OpenAPI spec: https://www.oanor.com/api/poolchem-api/openapi.json
