skimmer
API Reference

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/json

No authentication required.


Request Body

FieldTypeRequiredDescription
readingsobjectYesCurrent pool water readings as {reading_id: value}. See reading IDs.
poolobjectYesPool information. See pool object.
formula_idstringNoOverride the auto-resolved formula. See formula IDs. If omitted, resolved from pool.water_type.
target_levelsarrayNoOverride target ranges (highest priority). See target levels.
substitutionsobjectNoOverride default treatments. See substitutions.

Pool Object

FieldTypeRequiredDescription
gallonsnumberYesPool volume in gallons.
water_typestringNoSanitization method. Used to auto-resolve the formula. One of: chlorine, salt_water, bromine, minerals, biguanide, copper, ozone, uv. Defaults to chlorine if omitted.
wall_typestringNoPool 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_typeResolved Formula
chlorine (default)skimmer-chlorine_cal_hypo
salt_waterskimmer-salt
bromineskimmer-bromine
mineralsskimmer-minerals
biguanideskimmer-biguanide
ozone, uvskimmer-chlorine_cal_hypo
copperskimmer-minerals

Target Range Priority

Target ranges are resolved in this order (highest priority wins):

  1. Reading defaults — built into each reading (e.g. pH 7.2–7.6)
  2. Formula-level overrides — per-formula adjustments (e.g. salt CYA 60–80)
  3. Wall-type overrides — automatic for porous surfaces (plaster/concrete/pebble → CH 200–275)
  4. User-provided target_levels — your request body overrides everything

Target Levels

An array of objects to override target ranges:

FieldTypeDescription
idstringThe reading ID to override (e.g. "fc", "ph").
minnumberMinimum target value.
maxnumberMaximum target value.

Substitutions

Override the default treatment for a reading direction:

{
  "fc": { "up": "dichlor" },
  "ph": { "down": "sodium_bisulfate" }
}
FieldTypeDescription
upstringTreatment ID to use when raising this reading.
downstringTreatment 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

FieldTypeDescription
readingsarrayThe readings this action addresses. Each has id, name, short_name, units.
typestringOne of "raise", "lower", "special", "warning".
treatmentobjectThe recommended treatment.
ouncesnumberAmount in ounces. For warnings: delta from ideal. For waits: minutes.
treatment_optionsarrayAlternative treatments the user can choose from.

Treatment Object

FieldTypeDescription
idstringTreatment identifier.
namestringDisplay name.
typestringOne of "dryChemical", "liquidChemical", "task", "wait", "warning".
concentrationnumberPercent active ingredient (0-100).
descriptionstringInstructions for applying the treatment.
waitMinutesnumberMinutes to wait after applying before the next treatment.
taskNamestring(Optional) Short name for task-type treatments.

Formula IDs

IDNameDescription
skimmer-chlorine_cal_hypoSkimmer ChlorineStandard chlorine pools. pH: 7.2–7.6, TA: 80–120.
skimmer-saltSkimmer SaltSalt water pools. CYA: 60–80.
skimmer-bromineSkimmer BromineBromine pools.
skimmer-mineralsSkimmer MineralsMineral system pools. FC: 0.5–4.
skimmer-biguanideSkimmer BiguanideBiguanide pools. No chlorine/bromine.

Reading IDs

IDNameUnitsDefault TargetNotes
fcFree Chlorineppm1 – 3Warning: +2 above max
tcTotal ChlorineppmOffset by FC. Used to infer CC.
ccCombined Chlorineppm0 – 0.1Inferred: TC − FC. Triggers shock.
phpH7.2 – 7.6
taTotal Alkalinityppm80 – 120Warning: +20 above, +10 below
cyaStabilizer (CYA)ppm30 – 5060–80 for salt pools. Warning: ±10
chCalcium Hardnessppm175 – 225200–275 for plaster/concrete/pebble. Warning: ±25
saltSalt Levelppm2700 – 3500Salt pools only.
broBromineppm3 – 5Bromine pools only.
phosphatePhosphateppb0 – 200
ironIronppm0 – 0.2
copperCopperppm0 – 0.2
tdsTDSppm500 – 1500
borateBorateppm70 – 90
biguanideBiguanideppm30 – 70Biguanide pools only.
biguanide_shockBiguanide Shockppm100 – 300Biguanide pools only.
temp_fWater Temperature°FMonitoring only. No treatment.

Treatment IDs

Chemical Treatments

IDNameTypeWait
calc_hypoChlorine GranulesdryChemical15 min
na_hcloLiquid ChlorineliquidChemical60 min
chlorine_tabletsChlorine Tabletstask60 min
dichlorDichlordryChemical15 min
bromineBrominedryChemical20 min
soda_ashSoda AshdryChemical20 min
ph_increaserpH IncreaserdryChemical20 min
m_acidMuriatic AcidliquidChemical20 min
sodium_bisulfatepH DecreaserdryChemical20 min
baking_sodaBaking SodadryChemical20 min
alk_increaserAlkalinity IncreaserdryChemical20 min
cal_chlorHardness IncreaserdryChemical480 min
cyaStabilizerdryChemical20 min
saltPool SaltdryChemical0 min
shockChlorine ShockdryChemical480 min
iron_removerMetal Remover (Iron)liquidChemical60 min
copper_removerMetal Remover (Copper)liquidChemical60 min
borate_increaserBorate IncreaserdryChemical20 min
biguanide_sanitizerBiguanide SanitizerliquidChemical20 min
biguanide_oxidizerBiguanide OxidizerliquidChemical20 min
phosphate_remPhosphate RemoverliquidChemical60 min

Task / Special Treatments

IDNameDescription
swg_upIncrease SWG OutputTurn up the salt chlorine generator dial.
drainDilute PoolPartial drain and refill.
drain_fcDilute Pool (FC)Stop adding chlorine or partial drain.
drain_cyaDilute Pool (CYA)Stop stabilized chlorine, partial drain.
drain_chDilute Pool (CH)Partial drain with hose filter.
tds_drainDrain & Refill (TDS)Partial drain to lower TDS.
waitWaitAuto-inserted between treatments. ounces = minutes.
warningWarningReading 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" }