QuickFreeze QFM API
Read live status and control your QFM units from your WMS or building-automation system — set cycle times, record what is on the pallet, pause and resume fans.
Your software addresses each unit by its QFM serial number (printed on the unit) plus the rack location you have on file for it. Everything runs through one secured endpoint, scoped to your facility’s own units. The serial is permanent — when a control box is replaced, the API resolves the serial to whichever box is installed at that moment, so a swap needs no change on your side.
Connection
- Endpoint
https://qfreeze.com/wp-json/qf/v1/qfm
the same address for every customer — your key scopes it to your units- Auth header
X-QF-API-Key: {your-api-key}— issued per facility; TLS 1.2+ required- Methods
- HTTP GET (query parameters) or POST (JSON body)
- Responses
- Reads return 200 with the unit’s live state; commands return 202 accepted. Every failure is JSON with a stable
errorcode — a missing or wrong key returns 401. - User-Agent
- Please send an identifying agent, e.g.
YourCompany-WMS/1.0. Our edge blocks a few known automated-client signatures; if you ever receive an HTML 403 instead of JSON, tell us and we will allow your client.
1. Identifying a unit
Every request carries two identifiers, and both must match our records:
| Parameter | Example | Notes |
|---|---|---|
QFM_SERIAL | QFM-12107 | Printed on the unit. Permanent — survives control-box swaps. |
RACK_LOCATION | 2X-001B | The rack position we have recorded for that QFM. |
WAREHOUSE_ID | DC-EAST | Optional. Your own site or warehouse code, echoed back unchanged — a label for multi-site systems, not a permission. |
If the serial exists but the rack does not match, the request is refused and the reply
tells you which rack we have on file (409 rack_mismatch). A stale or mis-keyed mapping in the
WMS can never make us act on the wrong unit. A serial belonging to another customer returns
403, even with a correct rack.
2. Poll a unit (read latest)
COMMAND=poll is the default and may be omitted. Polling is read-only and cannot affect equipment.
curl -H "X-QF-API-Key: {your-api-key}" -H "User-Agent: YourCompany-WMS/1.0" \
"https://qfreeze.com/wp-json/qf/v1/qfm?QFM_SERIAL=QFM-12107&RACK_LOCATION=2X-001B&COMMAND=poll"
→ 200 {"ok":true,"QFM_SERIAL":"QFM-12107","RACK_LOCATION":"2X-001B",
"controlBox":"F8B3B74E6E7C","ts":1786143610000,"state":"READY",
"airtF":3.4,"airtC":-15.89,"deltap":0.01,
"remaining":172800,"active":true,"SKU":"I1-123456"}
| Field | Meaning |
|---|---|
ok | true on success. Always present. |
RACK_LOCATION | The rack we have on file for the unit. |
controlBox | The control box installed right now. Opaque to you — quote it when reporting an issue. |
ts | Time of the reading, epoch milliseconds UTC. Always check it: an offline unit returns its last known values with an older timestamp. |
state | Current unit state, e.g. READY, RUNNING, COMPLETE, PAUSE, BAD SEAL. |
airtF / airtC | Air temperature in both scales. Units measure in Celsius — read airtF if you work in Fahrenheit; do not assume an unlabelled value is °F. |
deltap | Differential pressure across the unit (seal quality). |
remaining | Seconds remaining in the current cycle; 0 when not running. |
active | Whether the unit is currently running. |
SKU | Item code stamped on the cycle in progress (always a string). Empty when no cycle is running — the unit clears it at cycle end. |
3. Commands
Three commands are available: set_cycle, pause and resume.
Commands are asynchronous: we validate and authorise the request, return
202, then apply it to the unit a moment later. Anything we cannot act on is
rejected up front with a 4xx and an error code — we never return 202 for a
command that would quietly do nothing. To confirm a change reached the unit, poll it afterwards.
Set cycle time and cycle details — set_cycle
| Parameter | Notes |
|---|---|
INCUBATION | Run time in hours, whole or fractional (48, 12.5). Persists until changed; if the unit is offline it takes effect at its next check-in. |
ITEM_NUMBER (or SKU) | Your item code. Stamped on the unit for this cycle, and can supply the run time from your SKU library (below). |
PALLET_TAG, PO | Pallet / LP / LPN and purchase order, recorded against the cycle for reporting. |
Send any combination — at least one. Only PO? Fine. Pallet details on a cycle that is
already running, without touching its run time? Fine. If you send any of these fields without a
COMMAND, we treat it as set_cycle.
curl -H "X-QF-API-Key: {your-api-key}" -H "User-Agent: YourCompany-WMS/1.0" \
"https://qfreeze.com/wp-json/qf/v1/qfm?QFM_SERIAL=QFM-12107&RACK_LOCATION=2X-001B\
&COMMAND=set_cycle&INCUBATION=48&ITEM_NUMBER=I1-123456&PALLET_TAG=LP-4471&PO=PO12345"
→ 202 {"ok":true,"accepted":true,"QFM_SERIAL":"QFM-12107","RACK_LOCATION":"2X-001B",
"controlBox":"F8B3B74E6E7C","COMMAND":"set_cycle",
"applied":{"cycleTimeHours":48,"SKU":"I1-123456","PALLET_TAG":"LP-4471","PO":"PO12345"},
"cycleTimeChanged":true}
applied lists exactly what we acted on and cycleTimeChanged says whether the
run time moved — you never have to assume. An INCUBATION we cannot use rejects the whole
call; we will not quietly apply just the metadata.
Cycle time from the SKU
Let the item code decide the run time instead of sending INCUBATION every call:
&COMMAND=set_cycle&ITEM_NUMBER=I1-123456. The library builds itself from your calls: the
first call that carries an item code with an explicit INCUBATION teaches us that
item’s run time, and later calls can send the code alone. A new item without hours is registered but
the run time is left unchanged — the reply says so with cycleTimeChanged:false and a
warning. An explicit INCUBATION always wins.
Pause / resume fans
pause stops the fans and freezes the cycle timer in place; resume
continues from exactly where it stopped. DURATION (minutes, optional) is a dead-man
auto-resume: if your system never sends resume, the unit restores itself. We recommend sending
it on every pause.
curl -H "X-QF-API-Key: {your-api-key}" \
"https://qfreeze.com/wp-json/qf/v1/qfm?QFM_SERIAL=QFM-12107&RACK_LOCATION=2X-001B&COMMAND=pause&DURATION=30"
curl -H "X-QF-API-Key: {your-api-key}" \
"https://qfreeze.com/wp-json/qf/v1/qfm?QFM_SERIAL=QFM-12107&RACK_LOCATION=2X-001B&COMMAND=resume"
READY a moment after being paused — that is the unit behaving correctly, not a
failed command. Check state and active first if it matters to your workflow.Repeating a command
All three commands are safe to send again — set_cycle sets a value rather than adding
to one, and pause/resume set a state. Re-sending after a timeout will not compound.
4. Error responses
Alert on the error code, not the message text — messages may be reworded, codes will not change.
{"ok":false,"error":"rack_mismatch",
"message":"RACK_LOCATION does not match the rack recorded for QFM-12107. Refusing to act on a possibly wrong unit.",
"expectedRackLocation":"2X-001B"}
| HTTP | error | Meaning | What to do |
|---|---|---|---|
| 400 | missing_serial / missing_rack_location | A required identifier is absent | Fix the request |
| 400 | bad_command | Unrecognised COMMAND | Fix the request |
| 400 | nothing_to_set | set_cycle with nothing to apply | Send at least one field |
| 400 | poll_is_read_only | COMMAND=poll sent with fields that would write | Omit COMMAND, or use set_cycle |
| 400 | bad_cycle_time | INCUBATION not a positive number | Fix the value — nothing was applied |
| 401 | unauthorized | Missing or wrong API key | Check the header; alert |
| 403 | not_authorized | That unit is not on your account | Check the serial; alert |
| 404 | unknown_serial | No QFM with that serial | Typo or decommissioned unit; alert |
| 409 | rack_mismatch | Serial is yours, rack does not match | Alert. Your mapping is stale — expectedRackLocation tells you ours |
| 409 | ambiguous_serial | Serial matches more than one unit | Contact us — a data issue on our side |
| 502 | upstream_error | We could not reach the monitoring platform | Retry with backoff; alert if sustained |
Retries: poll and all commands are safe to retry. Use exponential backoff on 502; do not retry 4xx — they will not succeed without a change to the request.
Identity & safety
- Each facility authenticates with its own API key and is authorised to its own units only.
RACK_LOCATIONmust match the location mapped to thatQFM_SERIALor the request is refused — this prevents adjusting the wrong unit.- Units are addressed by QFM serial, which stays stable across control-box swaps;
controlBoxin every response shows which box answered. - Keep your API key out of email threads and shared files. QuickFreeze may rate-limit excessive request volumes.
Getting started
QuickFreeze issues your API key and the QFM_SERIAL ↔ RACK_LOCATION map for your units.
A good first call is a poll against one live unit, then a deliberately wrong rack location to see
409 rack_mismatch come back. Send us your SKU list with cycle times if you want
ITEM_NUMBER alone to set run times from day one.
To request access, contact your QuickFreeze representative.
