Emergency Lockdown Workflow

Lock down all doors immediately during security incidents in 3 minutes

3 mins
Beginner

Complete code to lock down all doors immediately during security incidents. Fast, simple, and reversible.

The Workflow

Scenario: Security incident. Need to lock down entire building immediately.

What we'll do

Get all channels (doors)
Set each to lockdown mode
Verify lockdown complete

Time: About 2-5 seconds (depends on number of doors)

When to Use

Emergency lockdown for

Active security threat
Fire alarm (if building requires lockdown)
Evacuation procedures
After-hours security
Testing emergency procedures

How it works

Lockdown mode locks all doors
No credentials work (cards, PINs, mobile)
Doors remain locked until manually restored to normal

Quick Lockdown Script

Bash Version

Fast command-line lockdown:

bash
#!/bin/bash
# Emergency Lockdown Script
# Usage: ./lockdown.sh

ACCESS_TOKEN="your_access_token_here"
BASE_URL="https://api.doorflow.com/api/3"

echo "INITIATING EMERGENCY LOCKDOWN..."
echo ""

# Get all channels
CHANNELS_RESPONSE=$(curl -s -X GET "$BASE_URL/channels" \
  -H "Authorization: Bearer $ACCESS_TOKEN")

# Extract channel IDs
CHANNEL_IDS=$(echo $CHANNELS_RESPONSE | jq -r '.channels[].id')
CHANNEL_COUNT=$(echo $CHANNEL_IDS | wc -w)

echo "Locking down $CHANNEL_COUNT doors..."
echo ""

# Lockdown each channel
for CHANNEL_ID in $CHANNEL_IDS; do
  CHANNEL_NAME=$(echo $CHANNELS_RESPONSE | jq -r ".channels[] | select(.id==$CHANNEL_ID) | .name")

  echo "Locking: $CHANNEL_NAME (ID: $CHANNEL_ID)..."

  curl -s -X POST "$BASE_URL/channels/$CHANNEL_ID/lockdown" \
    -H "Authorization: Bearer $ACCESS_TOKEN" > /dev/null

  echo "[OK] $CHANNEL_NAME locked down"
done

echo ""
echo "============================="
echo "LOCKDOWN COMPLETE"
echo "============================="
echo ""
echo "All $CHANNEL_COUNT doors are now in lockdown mode."
echo "No credentials will grant access."
echo ""
echo "To restore normal operation: ./unlock_all.sh"

Save as: lockdown.sh

Run:

bash
chmod +x lockdown.sh
./lockdown.sh

JavaScript Version

javascript
async function emergencyLockdown() {
  const accessToken = process.env.DOORFLOW_ACCESS_TOKEN;
  const baseURL = 'https://api.doorflow.com/api/3';

  try {
    console.log('INITIATING EMERGENCY LOCKDOWN...\n');

    // Step 1: Get all channels
    const channelsResponse = await fetch(`${baseURL}/channels`, {
      headers: {
        'Authorization': `Bearer ${accessToken}`,
      },
    });

    if (!channelsResponse.ok) {
      throw new Error(`Failed to get channels: ${await channelsResponse.text()}`);
    }

    const { channels } = await channelsResponse.json();
    console.log(`Locking down ${channels.length} doors...\n`);

    // Step 2: Lockdown each channel
    const results = [];

    for (const channel of channels) {
      try {
        console.log(`Locking: ${channel.name} (ID: ${channel.id})...`);

        const lockdownResponse = await fetch(`${baseURL}/channels/${channel.id}/lockdown`, {
          method: 'POST',
          headers: {
            'Authorization': `Bearer ${accessToken}`,
          },
        });

        if (lockdownResponse.ok) {
          console.log(`[OK] ${channel.name} locked down`);
          results.push({ channelId: channel.id, name: channel.name, success: true });
        } else {
          console.log(`[ERROR] Failed to lock ${channel.name}`);
          results.push({ channelId: channel.id, name: channel.name, success: false });
        }

      } catch (error) {
        console.error(`[ERROR] ${channel.name}: ${error.message}`);
        results.push({ channelId: channel.id, name: channel.name, success: false, error: error.message });
      }
    }

    // Summary
    const successful = results.filter(r => r.success);
    const failed = results.filter(r => !r.success);

    console.log('\n=============================');
    console.log('LOCKDOWN COMPLETE');
    console.log('=============================\n');
    console.log(`Doors locked: ${successful.length}`);
    console.log(`Failed: ${failed.length}`);

    if (failed.length > 0) {
      console.log('\nFailed doors:');
      failed.forEach(f => console.log(`  - ${f.name} (ID: ${f.channelId})`));
    }

    console.log('\nAll doors are in lockdown mode.');
    console.log('No credentials will grant access.');
    console.log('\nTo restore: unlockAll()');

    return {
      totalDoors: channels.length,
      locked: successful.length,
      failed: failed.length,
      results: results,
    };

  } catch (error) {
    console.error('LOCKDOWN FAILED:', error);
    throw error;
  }
}

// Usage
emergencyLockdown()
  .then(result => {
    console.log('\nLockdown result:', result);
  })
  .catch(error => {
    console.error('Error:', error.message);
  });

Restore Normal Operation

Unlock all doors after emergency is over:

Bash Version

bash
#!/bin/bash
# Restore Normal Operation Script
# Usage: ./unlock_all.sh

ACCESS_TOKEN="your_access_token_here"
BASE_URL="https://api.doorflow.com/api/3"

echo "Restoring normal operation..."
echo ""

# Get all channels
CHANNELS_RESPONSE=$(curl -s -X GET "$BASE_URL/channels" \
  -H "Authorization: Bearer $ACCESS_TOKEN")

CHANNEL_IDS=$(echo $CHANNELS_RESPONSE | jq -r '.channels[].id')

# Restore each channel to normal
for CHANNEL_ID in $CHANNEL_IDS; do
  CHANNEL_NAME=$(echo $CHANNELS_RESPONSE | jq -r ".channels[] | select(.id==$CHANNEL_ID) | .name")

  curl -s -X POST "$BASE_URL/channels/$CHANNEL_ID/normal" \
    -H "Authorization: Bearer $ACCESS_TOKEN" > /dev/null

  echo "[OK] $CHANNEL_NAME restored to normal"
done

echo ""
echo "[OK] All channels restored to normal operation"
echo "[OK] Access control is now active"

JavaScript Version

javascript
async function unlockAll() {
  const accessToken = process.env.DOORFLOW_ACCESS_TOKEN;
  const baseURL = 'https://api.doorflow.com/api/3';

  try {
    console.log('Restoring normal operation...\n');

    // Get all channels
    const channelsResponse = await fetch(`${baseURL}/channels`, {
      headers: {
        'Authorization': `Bearer ${accessToken}`,
      },
    });

    const { channels } = await channelsResponse.json();
    console.log(`Restoring ${channels.length} doors...\n`);

    // Restore each channel to normal mode
    for (const channel of channels) {
      console.log(`Restoring: ${channel.name}...`);

      await fetch(`${baseURL}/channels/${channel.id}/normal`, {
        method: 'POST',
        headers: {
          'Authorization': `Bearer ${accessToken}`,
        },
      });

      console.log(`[OK] ${channel.name} restored`);
    }

    console.log('\n[OK] All channels restored to normal operation');
    console.log('[OK] Access control is now active');

    return {
      totalDoors: channels.length,
      restored: channels.length,
    };

  } catch (error) {
    console.error('Restore failed:', error);
    throw error;
  }
}

// Usage
unlockAll()
  .then(result => console.log('Restore complete:', result))
  .catch(error => console.error('Error:', error.message));

Selective Lockdown

Lock down specific doors only (e.g., one floor):

javascript
async function selectiveLockdown(channelIds) {
  const accessToken = process.env.DOORFLOW_ACCESS_TOKEN;
  const baseURL = 'https://api.doorflow.com/api/3';

  try {
    console.log(`Locking down ${channelIds.length} specific doors...\n`);

    for (const channelId of channelIds) {
      // Get channel name for logging
      const channelResponse = await fetch(`${baseURL}/channels/${channelId}`, {
        headers: { 'Authorization': `Bearer ${accessToken}` },
      });

      const channel = await channelResponse.json();
      console.log(`Locking: ${channel.name}...`);

      // Lockdown this channel
      await fetch(`${baseURL}/channels/${channelId}/lockdown`, {
        method: 'POST',
        headers: {
          'Authorization': `Bearer ${accessToken}`,
        },
      });

      console.log(`[OK] ${channel.name} locked down`);
    }

    console.log('\n[OK] Selective lockdown complete');

    return {
      doorsLocked: channelIds.length,
    };

  } catch (error) {
    console.error('Selective lockdown failed:', error);
    throw error;
  }
}

// Usage: Lock down only floors 2 and 3
const floor2And3Doors = [1340, 1341, 1342, 1343];
selectiveLockdown(floor2And3Doors)
  .then(result => console.log('Selective lockdown complete:', result));

Lockdown Status Check

Verify which doors are in lockdown:

javascript
async function checkLockdownStatus() {
  const accessToken = process.env.DOORFLOW_ACCESS_TOKEN;
  const baseURL = 'https://api.doorflow.com/api/3';

  try {
    // Get all channels
    const channelsResponse = await fetch(`${baseURL}/channels`, {
      headers: { 'Authorization': `Bearer ${accessToken}` },
    });

    const { channels } = await channelsResponse.json();

    // Check mode of each channel
    const lockdownDoors = [];
    const normalDoors = [];

    for (const channel of channels) {
      if (channel.mode === 'lockdown') {
        lockdownDoors.push(channel);
      } else if (channel.mode === 'normal') {
        normalDoors.push(channel);
      }
    }

    console.log('Lockdown Status:\n');
    console.log(`Doors in lockdown: ${lockdownDoors.length}`);
    console.log(`Doors normal: ${normalDoors.length}`);

    if (lockdownDoors.length > 0) {
      console.log('\nDoors in lockdown:');
      lockdownDoors.forEach(d => console.log(`  - ${d.name} (ID: ${d.id})`));
    }

    return {
      totalDoors: channels.length,
      lockdownDoors: lockdownDoors.length,
      normalDoors: normalDoors.length,
      lockedDownList: lockdownDoors,
    };

  } catch (error) {
    console.error('Status check failed:', error);
    throw error;
  }
}

// Usage
checkLockdownStatus()
  .then(result => console.log('Status:', result));

Lockdown with Notification

Send alerts when lockdown is activated:

javascript
async function lockdownWithAlert(reason) {
  try {
    console.log(`EMERGENCY LOCKDOWN: ${reason}\n`);

    // Lockdown all doors
    const result = await emergencyLockdown();

    // Log the incident
    await db.insert('security_incidents', {
      type: 'lockdown',
      reason: reason,
      initiated_by: currentUser.id,
      initiated_at: new Date(),
      doors_locked: result.locked,
    });

    // Send alerts
    await sendEmergencyAlerts({
      type: 'lockdown',
      reason: reason,
      doorsLocked: result.locked,
      time: new Date(),
    });

    console.log('[OK] Emergency alerts sent');

    return result;

  } catch (error) {
    console.error('Lockdown with alert failed:', error);
    throw error;
  }
}

async function sendEmergencyAlerts(details) {
  // Email security team
  await emailService.send({
    to: ['security@company.com', 'facilities@company.com'],
    subject: `EMERGENCY: Building Lockdown Activated`,
    body: `
      Emergency lockdown has been activated.

      Reason: ${details.reason}
      Time: ${details.time.toLocaleString()}
      Doors locked: ${details.doorsLocked}

      All building access is now restricted.
    `,
    priority: 'high',
  });

  // SMS security team
  await smsService.send({
    to: ['+1234567890', '+0987654321'],
    message: `EMERGENCY LOCKDOWN: ${details.reason}. ${details.doorsLocked} doors locked at ${details.time.toLocaleTimeString()}`,
  });

  // Post to Slack security channel
  await slackApp.client.chat.postMessage({
    channel: '#security-alerts',
    text: `EMERGENCY LOCKDOWN ACTIVATED`,
    blocks: [
      {
        type: 'section',
        text: {
          type: 'mrkdwn',
          text: `*EMERGENCY: Building Lockdown*\n\nReason: ${details.reason}\nTime: ${details.time.toLocaleString()}\nDoors locked: ${details.doorsLocked}`,
        },
      },
    ],
  });
}

// Usage
lockdownWithAlert('Active security threat in building')
  .then(result => console.log('Lockdown complete with alerts sent'));

Best Practices

1. Test lockdown regularly:

javascript
// Monthly lockdown test
async function testLockdown() {
  console.log('LOCKDOWN TEST - This is a drill\n');

  await emergencyLockdown();

  // Wait 30 seconds
  await new Promise(resolve => setTimeout(resolve, 30000));

  await unlockAll();

  console.log('LOCKDOWN TEST COMPLETE');
}

2. Log all lockdowns:

javascript
// Always log lockdown events
await db.insert('lockdown_log', {
  initiated_by: currentUser.id,
  reason: reason,
  doors_locked: result.locked,
  timestamp: new Date(),
});

3. Verify lockdown succeeded:

javascript
async function verifyLockdown() {
  const status = await checkLockdownStatus();

  if (status.normalDoors > 0) {
    console.log('[WARNING] Some doors not in lockdown!');
    return false;
  }

  console.log('[OK] All doors locked down');
  return true;
}

4. Have manual override process

Physical key override at doors
Manual unlock button inside building
Don't rely solely on API

5. Document lockdown procedures

Who can initiate lockdown
When to use lockdown
How to restore normal operation
Emergency contact numbers

Channel Modes Reference

Available modes

normal - Standard access control (credentials work)
lockdown - All access denied (no credentials work)
unlock - Door stays unlocked (anyone can enter)

Set mode:

bash
# Lockdown
POST /api/3/channels/{channel_id}/lockdown

# Normal
POST /api/3/channels/{channel_id}/normal

# Unlock (open)
POST /api/3/channels/{channel_id}/unlock

Required OAuth Scopes

  • account.channel.readonly - List channels
  • account.channel.admit - Change channel modes

Next Steps

[After-Hours Access] - Remote unlock for specific people
[Events and Audit Trail] - Monitor lockdown events

Learn more

[Core Resources] - Understanding channels
[Access Control Model] - How access works