Skimmer API Reference
Calculate pool chemical dosing recommendations using Skimmer formulas.
The Skimmer endpoint automatically resolves the formula from your pool's sanitization type and applies wall-type target overrides — you only need to provide readings and pool size.
Endpoint
POST https://api.poolcloud.com/api/skimmer/
Content-Type: application/jsonNo authentication required.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
readings | object | Yes | Current pool water readings as {reading_id: value}. See reading IDs. |
pool | object | Yes | Pool information. See pool object. |
formula_id | string | No | Override the auto-resolved formula. See formula IDs. If omitted, resolved from pool.water_type. |
target_levels | array | No | Override target ranges (highest priority). See target levels. |
substitutions | object | No | Override default treatments. See substitutions. |
Pool Object
| Field | Type | Required | Description |
|---|---|---|---|
gallons | number | Yes | Pool volume in gallons. |
water_type | string | No | Sanitization method. Used to auto-resolve the formula. One of: chlorine, salt_water, bromine, minerals, biguanide, copper, ozone, uv. Defaults to chlorine if omitted. |
wall_type | string | No | Pool surface material. One of: vinyl, plaster, fiberglass, concrete, pebble. Automatically adjusts calcium hardness target for porous surfaces. |
Formula Auto-Resolution
If formula_id is omitted, it is resolved from pool.water_type:
water_type | Resolved Formula |
|---|---|
chlorine (default) | skimmer-chlorine_cal_hypo |
salt_water | skimmer-salt |
bromine | skimmer-bromine |
minerals | skimmer-minerals |
biguanide | skimmer-biguanide |
ozone, uv | skimmer-chlorine_cal_hypo |
copper | skimmer-minerals |
Target Range Priority
Target ranges are resolved in this order (highest priority wins):
- Reading defaults — built into each reading (e.g. pH 7.2–7.6)
- Formula-level overrides — per-formula adjustments (e.g. salt CYA 60–80)
- Wall-type overrides — automatic for porous surfaces (plaster/concrete/pebble → CH 200–275)
- User-provided
target_levels— your request body overrides everything
Target Levels
An array of objects to override target ranges:
| Field | Type | Description |
|---|---|---|
id | string | The reading ID to override (e.g. "fc", "ph"). |
min | number | Minimum target value. |
max | number | Maximum target value. |
Substitutions
Override the default treatment for a reading direction:
{
"fc": { "up": "dichlor" },
"ph": { "down": "sodium_bisulfate" }
}| Field | Type | Description |
|---|---|---|
up | string | Treatment ID to use when raising this reading. |
down | string | Treatment ID to use when lowering this reading. |
Response
{
"actions": [
{
"readings": [
{ "id": "ph", "name": "pH", "short_name": "pH", "units": null }
],
"type": "raise",
"treatment": {
"id": "ph_increaser",
"name": "pH Increaser",
"type": "dryChemical",
"concentration": 100,
"description": "Sprinkle (or \"broadcast\") pH increaser directly over the surface of the pool...",
"waitMinutes": 20
},
"ounces": 11.2,
"treatment_options": [
{ "id": "ph_increaser", "name": "pH Increaser", "type": "dryChemical", "..." : "..." },
{ "id": "soda_ash", "name": "Soda Ash", "type": "dryChemical", "..." : "..." }
]
},
{
"readings": [],
"type": "special",
"treatment": { "id": "wait", "name": "Wait", "type": "wait" },
"ounces": 20,
"treatment_options": []
}
]
}Action Object
| Field | Type | Description |
|---|---|---|
readings | array | The readings this action addresses. Each has id, name, short_name, units. |
type | string | One of "raise", "lower", "special", "warning". |
treatment | object | The recommended treatment. |
ounces | number | Amount in ounces. For warnings: delta from ideal. For waits: minutes. |
treatment_options | array | Alternative treatments the user can choose from. |
Treatment Object
| Field | Type | Description |
|---|---|---|
id | string | Treatment identifier. |
name | string | Display name. |
type | string | One of "dryChemical", "liquidChemical", "task", "wait", "warning". |
concentration | number | Percent active ingredient (0-100). |
description | string | Instructions for applying the treatment. |
waitMinutes | number | Minutes to wait after applying before the next treatment. |
taskName | string | (Optional) Short name for task-type treatments. |
Formula IDs
| ID | Name | Description |
|---|---|---|
skimmer-chlorine_cal_hypo | Skimmer Chlorine | Standard chlorine pools. pH: 7.2–7.6, TA: 80–120. |
skimmer-salt | Skimmer Salt | Salt water pools. CYA: 60–80. |
skimmer-bromine | Skimmer Bromine | Bromine pools. |
skimmer-minerals | Skimmer Minerals | Mineral system pools. FC: 0.5–4. |
skimmer-biguanide | Skimmer Biguanide | Biguanide pools. No chlorine/bromine. |
Reading IDs
| ID | Name | Units | Default Target | Notes |
|---|---|---|---|---|
fc | Free Chlorine | ppm | 1 – 3 | Warning: +2 above max |
tc | Total Chlorine | ppm | — | Offset by FC. Used to infer CC. |
cc | Combined Chlorine | ppm | 0 – 0.1 | Inferred: TC − FC. Triggers shock. |
ph | pH | — | 7.2 – 7.6 | |
ta | Total Alkalinity | ppm | 80 – 120 | Warning: +20 above, +10 below |
cya | Stabilizer (CYA) | ppm | 30 – 50 | 60–80 for salt pools. Warning: ±10 |
ch | Calcium Hardness | ppm | 175 – 225 | 200–275 for plaster/concrete/pebble. Warning: ±25 |
salt | Salt Level | ppm | 2700 – 3500 | Salt pools only. |
bro | Bromine | ppm | 3 – 5 | Bromine pools only. |
phosphate | Phosphate | ppb | 0 – 200 | |
iron | Iron | ppm | 0 – 0.2 | |
copper | Copper | ppm | 0 – 0.2 | |
tds | TDS | ppm | 500 – 1500 | |
borate | Borate | ppm | 70 – 90 | |
biguanide | Biguanide | ppm | 30 – 70 | Biguanide pools only. |
biguanide_shock | Biguanide Shock | ppm | 100 – 300 | Biguanide pools only. |
temp_f | Water Temperature | °F | — | Monitoring only. No treatment. |
Treatment IDs
Chemical Treatments
| ID | Name | Type | Wait |
|---|---|---|---|
calc_hypo | Chlorine Granules | dryChemical | 15 min |
na_hclo | Liquid Chlorine | liquidChemical | 60 min |
chlorine_tablets | Chlorine Tablets | task | 60 min |
dichlor | Dichlor | dryChemical | 15 min |
bromine | Bromine | dryChemical | 20 min |
soda_ash | Soda Ash | dryChemical | 20 min |
ph_increaser | pH Increaser | dryChemical | 20 min |
m_acid | Muriatic Acid | liquidChemical | 20 min |
sodium_bisulfate | pH Decreaser | dryChemical | 20 min |
baking_soda | Baking Soda | dryChemical | 20 min |
alk_increaser | Alkalinity Increaser | dryChemical | 20 min |
cal_chlor | Hardness Increaser | dryChemical | 480 min |
cya | Stabilizer | dryChemical | 20 min |
salt | Pool Salt | dryChemical | 0 min |
shock | Chlorine Shock | dryChemical | 480 min |
iron_remover | Metal Remover (Iron) | liquidChemical | 60 min |
copper_remover | Metal Remover (Copper) | liquidChemical | 60 min |
borate_increaser | Borate Increaser | dryChemical | 20 min |
biguanide_sanitizer | Biguanide Sanitizer | liquidChemical | 20 min |
biguanide_oxidizer | Biguanide Oxidizer | liquidChemical | 20 min |
phosphate_rem | Phosphate Remover | liquidChemical | 60 min |
Task / Special Treatments
| ID | Name | Description |
|---|---|---|
swg_up | Increase SWG Output | Turn up the salt chlorine generator dial. |
drain | Dilute Pool | Partial drain and refill. |
drain_fc | Dilute Pool (FC) | Stop adding chlorine or partial drain. |
drain_cya | Dilute Pool (CYA) | Stop stabilized chlorine, partial drain. |
drain_ch | Dilute Pool (CH) | Partial drain with hose filter. |
tds_drain | Drain & Refill (TDS) | Partial drain to lower TDS. |
wait | Wait | Auto-inserted between treatments. ounces = minutes. |
warning | Warning | Reading slightly out of range. ounces = delta. |
Examples
Minimal Request
Just readings and pool size. Formula defaults to chlorine:
curl -X POST https://api.poolcloud.com/api/skimmer/ \
-H "Content-Type: application/json" \
-d '{
"readings": { "fc": 0, "ph": 7.0, "ta": 60 },
"pool": { "gallons": 10000 }
}'Salt Water Pool
Auto-resolves to skimmer-salt formula with CYA target 60–80:
curl -X POST https://api.poolcloud.com/api/skimmer/ \
-H "Content-Type: application/json" \
-d '{
"readings": {
"salt": 2000,
"fc": 2, "tc": 2,
"ph": 7.4, "ta": 100,
"cya": 40, "ch": 200
},
"pool": {
"gallons": 15000,
"water_type": "salt_water"
}
}'Plaster Pool with Auto CH Override
CH target automatically raised to 200–275 for plaster:
curl -X POST https://api.poolcloud.com/api/skimmer/ \
-H "Content-Type: application/json" \
-d '{
"readings": {
"fc": 2, "tc": 2,
"ph": 7.4, "ta": 100,
"cya": 40, "ch": 180
},
"pool": {
"gallons": 10000,
"wall_type": "plaster"
}
}'Biguanide Pool
No chlorine or bromine — uses biguanide sanitizer and oxidizer:
curl -X POST https://api.poolcloud.com/api/skimmer/ \
-H "Content-Type: application/json" \
-d '{
"readings": {
"biguanide": 20,
"biguanide_shock": 50,
"ph": 7.4, "ta": 100, "ch": 200
},
"pool": {
"gallons": 12000,
"water_type": "biguanide"
}
}'With Custom Target Levels
User overrides take highest priority:
curl -X POST https://api.poolcloud.com/api/skimmer/ \
-H "Content-Type: application/json" \
-d '{
"readings": { "fc": 2, "ph": 7.5, "ta": 100 },
"pool": { "gallons": 20000 },
"target_levels": [
{ "id": "fc", "min": 3, "max": 5 }
]
}'With Substitutions
Use dichlor instead of the default chlorine treatment:
curl -X POST https://api.poolcloud.com/api/skimmer/ \
-H "Content-Type: application/json" \
-d '{
"readings": { "fc": 1, "ph": 7.4 },
"pool": { "gallons": 15000 },
"substitutions": {
"fc": { "up": "dichlor" }
}
}'Error Responses
400 — Bad Request
Invalid formula_id or calculation error:
{ "error": "Calculation failed: Unknown formula_id \"invalid\". Valid IDs: skimmer-chlorine_cal_hypo, skimmer-salt, skimmer-bromine, skimmer-minerals, skimmer-biguanide" }422 — Validation Error
Missing required fields:
{ "error": "Validation error", "detail": "..." }504 — Timeout
{ "error": "Calculation timed out" }