About the VLSM Calculator API

API Version: 1.9

Plan variable-length subnets. Give it a parent network and the number of hosts each subnet needs, and it returns an allocation plan: the block assigned to each subnet, the spare addresses inside each block, what is left free, and the reasoning for every placement.

This is the API for the VLSM Calculator. See also: Subnet Calculator API.

Endpoints

https://networkcalc.com/api/vlsm/{parent}

Allocates the requested subnets inside the parent network. Subnets are sorted largest first and placed end to end, each on a boundary aligned to its own size.

Example request and response
curl https://networkcalc.com/api/vlsm/192.168.1.0/24?hosts=Sales%3A60%2CEngineering%3A28%2CManagement%3A10%2CWAN%20A%3A2%2CWAN%20B%3A2

{
  "status": "OK",
  "meta": {},
  "parent": {
    "cidr": "192.168.1.0/24",
    "network_address": "192.168.1.0",
    "broadcast_address": "192.168.1.255",
    "subnet_mask": "255.255.255.0",
    "total_addresses": 256
  },
  "allocations": [
    {
      "order": 1,
      "input_position": 1,
      "name": "Sales",
      "requested_hosts": 60,
      "cidr": "192.168.1.0/26",
      "network_address": "192.168.1.0",
      "broadcast_address": "192.168.1.63",
      "first_host": "192.168.1.1",
      "last_host": "192.168.1.62",
      "subnet_mask": "255.255.255.192",
      "wildcard_mask": "0.0.0.63",
      "prefix": 26,
      "block_size": 64,
      "usable_hosts": 62,
      "spare_hosts": 2,
      "offset": 0,
      "reason": "60 hosts + 2 reserved (network and broadcast) = 62 addresses. The smallest block that holds that is a /26 (64 addresses, 62 usable), leaving 2 spare. It is placed at the start of the parent network."
    },
    {
      "order": 2,
      "input_position": 2,
      "name": "Engineering",
      "requested_hosts": 28,
      "cidr": "192.168.1.64/27",
      "network_address": "192.168.1.64",
      "broadcast_address": "192.168.1.95",
      "first_host": "192.168.1.65",
      "last_host": "192.168.1.94",
      "subnet_mask": "255.255.255.224",
      "wildcard_mask": "0.0.0.31",
      "prefix": 27,
      "block_size": 32,
      "usable_hosts": 30,
      "spare_hosts": 2,
      "offset": 64,
      "reason": "28 hosts + 2 reserved (network and broadcast) = 30 addresses. The smallest block that holds that is a /27 (32 addresses, 30 usable), leaving 2 spare. It is placed at the next /27-aligned address after 192.168.1.0/26."
    },
    {
      "order": 3,
      "input_position": 3,
      "name": "Management",
      "requested_hosts": 10,
      "cidr": "192.168.1.96/28",
      "network_address": "192.168.1.96",
      "broadcast_address": "192.168.1.111",
      "first_host": "192.168.1.97",
      "last_host": "192.168.1.110",
      "subnet_mask": "255.255.255.240",
      "wildcard_mask": "0.0.0.15",
      "prefix": 28,
      "block_size": 16,
      "usable_hosts": 14,
      "spare_hosts": 4,
      "offset": 96,
      "reason": "10 hosts + 2 reserved (network and broadcast) = 12 addresses. The smallest block that holds that is a /28 (16 addresses, 14 usable), leaving 4 spare. It is placed at the next /28-aligned address after 192.168.1.64/27."
    },
    {
      "order": 4,
      "input_position": 4,
      "name": "WAN A",
      "requested_hosts": 2,
      "cidr": "192.168.1.112/30",
      "network_address": "192.168.1.112",
      "broadcast_address": "192.168.1.115",
      "first_host": "192.168.1.113",
      "last_host": "192.168.1.114",
      "subnet_mask": "255.255.255.252",
      "wildcard_mask": "0.0.0.3",
      "prefix": 30,
      "block_size": 4,
      "usable_hosts": 2,
      "spare_hosts": 0,
      "offset": 112,
      "reason": "2 hosts + 2 reserved (network and broadcast) = 4 addresses. The smallest block that holds that is a /30 (4 addresses, 2 usable), leaving 0 spare. It is placed at the next /30-aligned address after 192.168.1.96/28."
    },
    {
      "order": 5,
      "input_position": 5,
      "name": "WAN B",
      "requested_hosts": 2,
      "cidr": "192.168.1.116/30",
      "network_address": "192.168.1.116",
      "broadcast_address": "192.168.1.119",
      "first_host": "192.168.1.117",
      "last_host": "192.168.1.118",
      "subnet_mask": "255.255.255.252",
      "wildcard_mask": "0.0.0.3",
      "prefix": 30,
      "block_size": 4,
      "usable_hosts": 2,
      "spare_hosts": 0,
      "offset": 116,
      "reason": "2 hosts + 2 reserved (network and broadcast) = 4 addresses. The smallest block that holds that is a /30 (4 addresses, 2 usable), leaving 0 spare. It is placed at the next /30-aligned address after 192.168.1.112/30."
    }
  ],
  "unallocated": [],
  "free": {
    "addresses": 136,
    "ranges": [
      {
        "start": "192.168.1.120",
        "end": "192.168.1.255",
        "addresses": 136,
        "cidrs": [
          "192.168.1.120/29",
          "192.168.1.128/25"
        ]
      }
    ]
  },
  "summary": {
    "parent_addresses": 256,
    "allocated_addresses": 120,
    "free_addresses": 136,
    "allocated_percent": 46.9,
    "free_percent": 53.1,
    "requested_hosts": 102,
    "usable_hosts_in_allocations": 110,
    "spare_hosts_in_allocations": 8,
    "subnets_requested": 5,
    "subnets_allocated": 5
  },
  "map": {
    "size": 256,
    "segments": [
      {
        "name": "Sales",
        "cidr": "192.168.1.0/26",
        "offset": 0,
        "size": 64
      },
      {
        "name": "Engineering",
        "cidr": "192.168.1.64/27",
        "offset": 64,
        "size": 32
      },
      {
        "name": "Management",
        "cidr": "192.168.1.96/28",
        "offset": 96,
        "size": 16
      },
      {
        "name": "WAN A",
        "cidr": "192.168.1.112/30",
        "offset": 112,
        "size": 4
      },
      {
        "name": "WAN B",
        "cidr": "192.168.1.116/30",
        "offset": 116,
        "size": 4
      }
    ]
  }
}

Parameters

{parent}

(Required) The IPv4 network to divide, in CIDR notation. Must be /30 or larger.

Example: https://networkcalc.com/api/vlsm/192.168.1.0/24

hosts

(Required) A comma-separated list of the subnets to allocate, each as name:hosts or just hosts. Up to 64 subnets. Names are optional, up to 32 characters.

Example: https://networkcalc.com/api/vlsm/192.168.1.0/24?hosts=Sales:60,Engineering:28,Management:10

Response Codes

200
OK - Success. Every requested subnet was allocated.
400
NO_PARENT_SPECIFIED - The {parent} parameter was not specified.
400
INVALID_PARENT - The parent is not a valid IPv4 CIDR block.
400
PARENT_TOO_SMALL - The parent network must be /30 or larger.
400
NO_REQUIREMENTS_SPECIFIED - The hosts parameter was not specified.
400
INVALID_REQUIREMENT - One or more entries in hosts is not a whole number of hosts. The entries are listed in invalid.
400
TOO_MANY_REQUIREMENTS - More than 64 subnets were requested.
400
INSUFFICIENT_SPACE - The parent does not have room for every subnet. The response still includes the allocations that fit and the unallocated subnets that did not.

Response Formats

{
  "status": "[string] The status of the request.",
  "parent": {
    "cidr": "[string] The parent network in CIDR notation.",
    "network_address": "[string] The parent's network address.",
    "broadcast_address": "[string] The parent's broadcast address.",
    "subnet_mask": "[string] The parent's subnet mask.",
    "total_addresses": "[number] The number of addresses in the parent."
  },
  "allocations": "[array] The subnets that were placed, in address order. See VLSMAllocation",
  "unallocated": "[array] The subnets that did not fit, with the reason for each. Empty when status is OK.",
  "free": {
    "addresses": "[number] The number of addresses left unallocated.",
    "ranges": "[array] The free ranges, each with start, end, addresses and the cidrs that cover it."
  },
  "summary": {
    "parent_addresses": "[number] The number of addresses in the parent.",
    "allocated_addresses": "[number] The number of addresses assigned to subnets.",
    "free_addresses": "[number] The number of addresses left free.",
    "allocated_percent": "[number] The percentage of the parent that is allocated.",
    "free_percent": "[number] The percentage of the parent that is free.",
    "requested_hosts": "[number] The total hosts requested by the allocated subnets.",
    "usable_hosts_in_allocations": "[number] The total usable hosts across the allocated blocks.",
    "spare_hosts_in_allocations": "[number] Usable hosts in the allocated blocks beyond what was requested.",
    "subnets_requested": "[number] The number of subnets requested.",
    "subnets_allocated": "[number] The number of subnets that were placed."
  },
  "map": {
    "size": "[number] The size of the parent, for drawing it to scale.",
    "segments": "[array] Each allocation as a , ,  and __TEXT\t__DATA\t__OBJC\tothers\tdec\thex."
  }
}
{
  "order": "[number] The placement order (largest subnet first).",
  "input_position": "[number] The position of this subnet in the request.",
  "name": "[string] The subnet name.",
  "requested_hosts": "[number] The hosts requested.",
  "cidr": "[string] The block assigned, in CIDR notation.",
  "network_address": "[string] The block's network address.",
  "broadcast_address": "[string] The block's broadcast address.",
  "first_host": "[string] The first usable host address.",
  "last_host": "[string] The last usable host address.",
  "subnet_mask": "[string] The subnet mask in dotted-decimal notation.",
  "wildcard_mask": "[string] The wildcard mask in dotted-decimal notation.",
  "prefix": "[number] The prefix length of the block.",
  "block_size": "[number] The number of addresses in the block.",
  "usable_hosts": "[number] The usable hosts in the block.",
  "spare_hosts": "[number] Usable hosts beyond the number requested.",
  "offset": "[number] The block's offset, in addresses, from the start of the parent.",
  "reason": "[string] A plain-language explanation of the block size and placement."
}