Overview
A free ductulator API for HVAC duct sizing calculations. Submit airflow (CFM) and friction rate or velocity, get back round and rectangular duct dimensions. All requests are GET. No authentication required. Returns XML by default for Excel compatibility, or JSON for use in code.
Endpoint: https://rysercad.com/api.php
Parameters
| Parameter | Type | Description | |
|---|---|---|---|
| cfm | number | required | Airflow in cubic feet per minute |
| friction | number | optional | Friction rate in in.w.g./100ft. Default: 0.1. Used when mode=friction. |
| velocity | number | optional | Air velocity in FPM. Required when mode=velocity. |
| mode | string | optional | friction or velocity. Default: friction. |
| height | number | optional | Fix rectangular duct height in inches and solve for width. If omitted, height is calculated automatically. |
| format | string | optional | xml (default) or json. Use json for Python, Google Apps Script, or any HTTP client. |
Response Fields
| Field | Unit | Description |
|---|---|---|
| cfm | CFM | Airflow (echoed from input) |
| roundDiameter | in | Round duct diameter |
| roundArea | sq ft | Round duct cross-sectional area |
| roundVelocity | FPM | Air velocity in round duct |
| roundFriction | in.w.g./100ft | Friction rate in round duct |
| rectWidth | in | Rectangular duct width |
| rectHeight | in | Rectangular duct height |
| rectArea | sq ft | Rectangular duct cross-sectional area |
| rectVelocity | FPM | Air velocity in rectangular duct |
| rectEquivDia | in | Equivalent diameter of rectangular duct |
| rectFriction | in.w.g./100ft | Friction rate in rectangular duct |
| aspectRatio | — | Width-to-height ratio |
Excel Usage
Retrieve the full XML response in one cell, then extract individual fields with FILTERXML().
Basic — friction mode:
=WEBSERVICE("https://rysercad.com/api.php?cfm="&A1&"&friction="&B1)
Velocity mode:
=WEBSERVICE("https://rysercad.com/api.php?cfm="&A1&"&mode=velocity&velocity="&B1)
Fixed height:
=WEBSERVICE("https://rysercad.com/api.php?cfm="&A1&"&friction="&B1&"&height="&C1)
Extract round diameter from result in D1:
=FILTERXML(D1,"//roundDiameter")
Extract and round up rect width:
=ROUNDUP(FILTERXML(D1,"//rectWidth"),0)
Suggested column layout:
| A: CFM | B: Friction | C: Height Override | D: WEBSERVICE (raw XML) | E: Round Dia | F: Rect Width |
|---|---|---|---|---|---|
| 400 | 0.1 | 12 | =WEBSERVICE(...) | =FILTERXML(D1,"//roundDiameter") | =ROUNDUP(FILTERXML(D1,"//rectWidth"),0) |
Rate Limiting
60 requests per minute per IP address. Exceeding this returns an error in the response.
Google Sheets Usage
Use IMPORTXML() to pull individual fields directly — no intermediate cell needed.
Round diameter:
=IMPORTXML("https://rysercad.com/api.php?cfm="&A1&"&friction="&B1,"//roundDiameter")
Rect width with fixed height:
=IMPORTXML("https://rysercad.com/api.php?cfm="&A1&"&friction="&B1&"&height="&C1,"//rectWidth")
JSON Usage
Add &format=json to get a JSON response for use in Python, JavaScript, or any HTTP client.
Example request:
https://rysercad.com/api.php?cfm=400&friction=0.1&format=json
Example response:
{
"success": true,
"data": {
"cfm": "400",
"roundDiameter": "9.8",
"roundArea": "0.52",
"roundVelocity": "764",
"roundFriction": "0.100",
"rectWidth": "16.2",
"rectHeight": "8",
"rectArea": "0.90",
"rectVelocity": "445",
"rectEquivDia": "9.8",
"rectFriction": "0.100",
"aspectRatio": "2.0"
}
}
Python example:
import requests
r = requests.get("https://rysercad.com/api.php", params={
"cfm": 400,
"friction": 0.1,
"format": "json"
})
data = r.json()["data"]
print(data["roundDiameter"], data["rectWidth"], data["rectHeight"])
Error Response
XML error:
<duct><error>CFM must be greater than 0.</error></duct>
JSON error:
{"success": false, "error": "CFM must be greater than 0."}
Check for XML errors in Excel with: =FILTERXML(D1,"//error")