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
X-API-Key: <your-api-key>

Authentication

All requests require an API key via the X-API-Key header. Contact us to obtain your key.

curl -X POST https://api.poolcloud.com/api/skimmer/ \
  -H "X-API-Key: sk_live_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{ ... }'

Missing or invalid keys return 401:

{ "error": "Invalid or missing API key. Include X-API-Key header." }

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-vitalyse_chlorine
salt_waterskimmer-vitalyse_salt
bromineskimmer-vitalyse_bromine
mineralsskimmer-vitalyse_mineral
biguanideskimmer-biguanide
ozone, uvskimmer-vitalyse_chlorine
copperskimmer-vitalyse_mineral

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

Vitalyse Formulas

The default formulas use the Vitalyse chemical set (opens in a new tab) by Poolwerx, with branded treatments for chlorine, shock, and calcium hardness.

IDNameDescription
skimmer-vitalyse_chlorineSkimmer Vitalyse ChlorineChlorine pools using Vitalyse chemicals. pH: 7.2–7.6, TA: 80–120.
skimmer-vitalyse_saltSkimmer Vitalyse SaltSalt water pools using Vitalyse chemicals. CYA: 60–80.
skimmer-vitalyse_bromineSkimmer Vitalyse BromineBromine pools using Vitalyse chemicals.
skimmer-vitalyse_mineralSkimmer Vitalyse MineralsMineral system pools using Vitalyse chemicals. FC: 0.5–4.

Generic Formulas

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

Vitalyse Formula Treatments

All possible treatments returned by the 4 Vitalyse formulas (skimmer-vitalyse_*). These use Poolwerx's Vitalyse line (opens in a new tab) for sanitization, shock, and calcium, plus generic treatments for everything else.

IDNameTypeConc.WaitRaises / Lowers
vitalyse_chlorineVitalyse Rapid Release ChlorinedryChemical70%15 minRaises FC
vitalyse_dichlorVitalyse Stabilised Rapid ReleasedryChemical48%15 minRaises FC
vitalyse_shockVitalyse Shock N Swim PlusdryChemical48%480 minLowers CC
vitalyse_calciumVitalyse Calcium PrilldryChemical94%480 minRaises CH
ph_increaserpH IncreaserdryChemical100%20 minRaises pH
soda_ashSoda AshdryChemical100%20 minRaises pH (also raises TA)
sodium_bisulfatepH DecreaserdryChemical100%20 minLowers pH and TA
m_acidMuriatic AcidliquidChemical31%20 minLowers pH and TA
alk_increaserAlkalinity IncreaserdryChemical100%20 minRaises TA
baking_sodaBaking SodadryChemical100%20 minRaises TA
cyaStabilizer (CYA)dryChemical100%20 minRaises CYA
iron_removerMetal Remover (Iron)liquidChemical100%60 minLowers iron
copper_removerMetal Remover (Copper)liquidChemical100%60 minLowers copper
phosphate_remPhosphate RemoverliquidChemical100%60 minLowers phosphate
borate_increaserBorate IncreaserdryChemical100%20 minRaises borate
swg_upIncrease SWG Outputtask0 minRaises FC (salt only)
saltPool SaltdryChemical100%0 minRaises salt (salt only)
bromineBrominedryChemical100%20 minRaises bromine (bromine only)
drain_fcDilute Pool (FC)task0 minLowers FC
drain_cyaDilute Pool (CYA)task0 minLowers CYA
drain_chDilute Pool (CH)task0 minLowers CH
drainDilute Pooltask0 minLowers salt / bromine
tds_drainDrain & Refill (TDS)task0 minLowers TDS
waitWaitwaitAuto-inserted between steps
warningWarningwarningReading near edge of range

Generic Formula Treatments

Additional treatments used only by the generic (non-Vitalyse) formula variants.

IDNameTypeWait
calc_hypoChlorine GranulesdryChemical15 min
na_hcloLiquid ChlorineliquidChemical60 min
chlorine_tabletsChlorine Tabletstask60 min
dichlorDichlordryChemical15 min
cal_chlorHardness IncreaserdryChemical480 min
shockChlorine ShockdryChemical480 min
biguanide_sanitizerBiguanide SanitizerliquidChemical20 min
biguanide_oxidizerBiguanide OxidizerliquidChemical20 min
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 "X-API-Key: sk_live_your_key_here" \
  -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 "X-API-Key: sk_live_your_key_here" \
  -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 "X-API-Key: sk_live_your_key_here" \
  -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 "X-API-Key: sk_live_your_key_here" \
  -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 "X-API-Key: sk_live_your_key_here" \
  -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 "X-API-Key: sk_live_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "readings": { "fc": 1, "ph": 7.4 },
    "pool": { "gallons": 15000 },
    "substitutions": {
      "fc": { "up": "dichlor" }
    }
  }'

Error Responses

401 — Unauthorized

Missing or invalid API key:

{ "error": "Invalid or missing API key. Include X-API-Key header." }

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, skimmer-vitalyse_chlorine, skimmer-vitalyse_salt, skimmer-vitalyse_bromine, skimmer-vitalyse_mineral" }

422 — Validation Error

Missing required fields:

{ "error": "Validation error", "detail": "..." }

504 — Timeout

{ "error": "Calculation timed out" }