Skip to main content

Overview

Control the thermostat’s fan independently of heating/cooling. Set the fan to always on, auto (runs with HVAC), or start a timed fan run.
Hosted service only. This endpoint is part of the hosted API at https://nolongerevil.com/api/v1 and requires an nle_ API key. It is not available on the self-hosted server.

Endpoint

POST https://nolongerevil.com/api/v1/thermostat/{deviceId}/fan

Authentication

Required Scopes: write

Request Body

For fan mode:
FieldTypeRequiredDescription
modestringYes"on", "auto", or "off"
For fan timer:
FieldTypeRequiredDescription
durationnumberYesDuration in seconds (max 43200 = 12 hours)

Example: Set Fan Mode

{
  "mode": "on"
}

Example: Start Fan Timer

{
  "duration": 900
}

Response

Success (200 OK):
{
  "success": true,
  "message": "Command handled",
  "device": "02AA01AB01234567",
  "object": "device.02AA01AB01234567",
  "revision": 90,
  "timestamp": 1764026410000
}

Fan Modes

ModeDescription
onFan runs continuously
autoFan runs only when heating/cooling is active
offFan off (system idle)
Fan timers automatically set the fan to auto mode after the duration expires.

Code Examples

curl -X POST https://nolongerevil.com/api/v1/thermostat/dev_abc123xyz/fan \
  -H "Authorization: Bearer nle_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{"mode": "on"}'
curl -X POST https://nolongerevil.com/api/v1/thermostat/dev_abc123xyz/fan \
  -H "Authorization: Bearer nle_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{"duration": 900}'
async function setFanMode(deviceId, mode) {
  const response = await fetch(
    `https://nolongerevil.com/api/v1/thermostat/${deviceId}/fan`,
    {
      method: 'POST',
      headers: {
        'Authorization': 'Bearer nle_your_api_key_here',
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({ mode })
    }
  );
  return await response.json();
}

async function startFanTimer(deviceId, durationSeconds) {
  const response = await fetch(
    `https://nolongerevil.com/api/v1/thermostat/${deviceId}/fan`,
    {
      method: 'POST',
      headers: {
        'Authorization': 'Bearer nle_your_api_key_here',
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({ duration: durationSeconds })
    }
  );
  return await response.json();
}

// Usage
await setFanMode('dev_abc123xyz', 'on'); // Fan always on
await startFanTimer('dev_abc123xyz', 900); // Run fan for 15 minutes
def set_fan_mode(device_id, mode):
    response = requests.post(
        f'https://nolongerevil.com/api/v1/thermostat/{device_id}/fan',
        headers={'Authorization': 'Bearer nle_your_api_key_here'},
        json={'mode': mode}
    )
    response.raise_for_status()
    return response.json()

def start_fan_timer(device_id, duration_seconds):
    response = requests.post(
        f'https://nolongerevil.com/api/v1/thermostat/{device_id}/fan',
        headers={'Authorization': 'Bearer nle_your_api_key_here'},
        json={'duration': duration_seconds}
    )
    response.raise_for_status()
    return response.json()

Use Cases

Air Circulation

// Run fan for 15 minutes every hour to circulate air
setInterval(async () => {
  await startFanTimer(deviceId, 15 * 60); // 15 minutes
}, 60 * 60 * 1000); // Every hour

Post-Cooking Ventilation

// Run fan after cooking to remove odors
await startFanTimer(deviceId, 30 * 60); // 30 minutes

Next Steps

Get Status

Check fan status

Set Temperature

Control temperature