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