# Water Hardness API
> Water-hardness maths as an API, computed locally and deterministically. The convert endpoint converts a hardness value between all the common units — parts per million / milligrams per litre as calcium carbonate, grains per US gallon, German degrees (°dH), French degrees (°f), English or Clark degrees, and millimoles per litre — passing everything through ppm (1 gpg = 17.118 ppm, 1 °dH = 17.848, 1 °f = 10, 1 °Clark = 14.254), and classifies the result. The classify endpoint labels a value as soft, moderately hard, hard or very hard on the USGS/WHO scale. The softener endpoint sizes a water softener: from the hardness and the household water use it works out the grains of hardness removed per day and the grain capacity needed between regenerations. Everything is computed locally and deterministically, so it is instant and private. Ideal for water-treatment and plumbing tools, aquarium and pool apps, appliance and softener sizing, and home and lab software. Pure local computation — no key, no third-party service, instant. Live, nothing stored. 3 endpoints. This is water-hardness conversion; for general unit conversion use a unit-conversion API and for swimming-pool dosing use a pool 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/hardness-api/..."
```

## Pricing
- **Free** (Free) — 12,135 calls/Mo, 2 req/s
- **Starter** ($14/Mo) — 21,750 calls/Mo, 8 req/s
- **Pro** ($34/Mo) — 267,500 calls/Mo, 20 req/s
- **Mega** ($72/Mo) — 1,380,000 calls/Mo, 50 req/s

## Endpoints

### Hardness

#### `GET /v1/classify` — Classify hardness

**Parameters:**
- `value` (query, required, string) — Hardness value Example: `150`
- `from` (query, optional, string) — Unit (default ppm) Example: `ppm`

**Example:**
```bash
curl -H "x-oanor-key: $KEY" \
  "https://api.oanor.com/hardness-api/v1/classify?value=150&from=ppm"
```

**Response:**
```json
{
    "data": {
        "note": "USGS/WHO hardness classification by ppm as CaCO₃.",
        "input": {
            "from": "ppm",
            "value": 150,
            "ppm_caco3": 150
        },
        "scale": [
            {
                "ppm": "0–60",
                "label": "soft"
            },
            {
                "ppm": "61–120",
                "label": "moderately hard"
            },
            {
                "ppm": "121–180",
                "label": "hard"
            },
            {
                "ppm": "> 180",
                "label": "very hard"
            }
        ],
        "classification": "hard"
    },
    "meta": {
        "timestamp": "2026-06-04T01:59:14.738Z",
        "request_id": "082d0218-8346-4048-a28c-0257b8a59ead"
    },
    "status": "ok",
    "message": "Hardness classification",
    "success": true
}
```

#### `GET /v1/convert` — Convert hardness units

**Parameters:**
- `value` (query, required, string) — Hardness value Example: `120`
- `from` (query, optional, string) — ppm|gpg|dH|fH|clark|mmol (default ppm) Example: `ppm`

**Example:**
```bash
curl -H "x-oanor-key: $KEY" \
  "https://api.oanor.com/hardness-api/v1/convert?value=120&from=ppm"
```

**Response:**
```json
{
    "data": {
        "note": "Converted via ppm (mg/L as CaCO₃). 1 gpg = 17.118 ppm; 1 °dH = 17.848; 1 °f = 10; 1 °Clark = 14.254.",
        "input": {
            "from": "ppm",
            "value": 120
        },
        "hardness": {
            "mg_per_l": 120,
            "french_fh": 12,
            "german_dh": 6.7234,
            "ppm_caco3": 120,
            "mmol_per_l": 1.19896,
            "english_clark": 8.4187,
            "grains_per_gallon": 7.0102
        },
        "classification": "moderately hard"
    },
    "meta": {
        "timestamp": "2026-06-04T01:59:14.836Z",
        "request_id": "bda8b020-ecea-44ae-aebf-abfab6b127da"
    },
    "status": "ok",
    "message": "Hardness conversion",
    "success": true
}
```

#### `GET /v1/softener` — Size a water softener

**Parameters:**
- `hardness` (query, required, string) — Hardness value Example: `10`
- `from` (query, optional, string) — Unit (default gpg) Example: `gpg`
- `people` (query, optional, string) — Household size (default 4) Example: `4`
- `gallons_per_person` (query, optional, string) — Daily use (default 80) Example: `80`
- `regen_days` (query, optional, string) — Days between regen (default 7) Example: `7`

**Example:**
```bash
curl -H "x-oanor-key: $KEY" \
  "https://api.oanor.com/hardness-api/v1/softener?hardness=10&from=gpg&people=4&gallons_per_person=80&regen_days=7"
```

**Response:**
```json
{
    "data": {
        "note": "Grains/day = daily water (gal) × hardness (gpg). Required capacity covers the days between regenerations; size the softener above this.",
        "input": {
            "from": "gpg",
            "people": 4,
            "hardness": 10,
            "regen_days": 7,
            "hardness_gpg": 10,
            "gallons_per_person": 80
        },
        "grains_per_day": 3200,
        "daily_water_gallons": 320,
        "required_grain_capacity": 22400
    },
    "meta": {
        "timestamp": "2026-06-04T01:59:14.921Z",
        "request_id": "4a021556-6d6c-4cee-922a-f2611d5eae1f"
    },
    "status": "ok",
    "message": "Water softener sizing",
    "success": true
}
```

### Meta

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

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

**Response:**
```json
{
    "data": {
        "note": "All conversions via ppm (mg/L as CaCO₃). Classification follows USGS/WHO bands.",
        "units": [
            "ppm",
            "gpg",
            "dH",
            "fH",
            "clark",
            "mmol"
        ],
        "service": "hardness",
        "endpoints": {
            "/v1/convert": "Convert a hardness value between all common units, with classification.",
            "/v1/classify": "Classify a hardness value (soft / moderately hard / hard / very hard).",
            "/v1/softener": "Size a water softener: grains per day and the grain capacity needed between regenerations."
        },
        "description": "Water-hardness maths: unit conversion (ppm/gpg/°dH/°f/Clark/mmol), classification, and water-softener sizing."
    },
    "meta": {
        "timestamp": "2026-06-04T01:59:14.992Z",
        "request_id": "e0c19e48-f2dd-41bd-9ab2-95a28a1f00a8"
    },
    "status": "ok",
    "message": "Meta",
    "success": true
}
```


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