Mental model
Meraki is cloud-managed, so there is no on-prem controller to log into. Your API calls go to api.meraki.com; Cisco routes them to your organisation.
Cisco objective 3.9.a says “Obtain a list of network devices by using Meraki, Cisco Catalyst Center, ACI, Cisco Catalyst SD-WAN, or NSO”. 3.9.c adds “Obtain a list of clients / hosts seen on a network using Meraki or Cisco Catalyst Center”. This topic covers the Meraki side; the pattern transfers to the others.
Credentials
- Log into dashboard.meraki.com with your account.
- Click your name (top right) → My profile.
- Find “API access”; click Generate new API key.
- Copy the key immediately. You cannot see it again.
- Treat it like a password: put it in
$MERAKI_API_KEY, add.envto.gitignore.
Base URL and the one required header
curl -H "X-Cisco-Meraki-API-Key: $MERAKI_API_KEY" \
https://api.meraki.com/api/v1/organizations
Response: a JSON array of orgs you have access to.
[
{"id": "123456", "name": "ACME Networks", "url": "https://n123.meraki.com/..."},
{"id": "789000", "name": "Lab Org", "url": "https://n789.meraki.com/..."}
]
Keep the id. Everything else keys off it.
List networks in an org
curl -H "X-Cisco-Meraki-API-Key: $MERAKI_API_KEY" \
https://api.meraki.com/api/v1/organizations/123456/networks
Returns an array of networks (each has id, name, productTypes, timeZone).
List devices in an org
curl -H "X-Cisco-Meraki-API-Key: $MERAKI_API_KEY" \
https://api.meraki.com/api/v1/organizations/123456/devices
Returns each device: serial, mac, name, model, networkId, firmware.
List clients on a specific device
curl -H "X-Cisco-Meraki-API-Key: $MERAKI_API_KEY" \
https://api.meraki.com/api/v1/devices/Q2XX-XXXX-XXXX/clients
Returns clients the device has seen recently: mac, ip, hostname, vlan, etc.
Create a new network
curl -X POST \
-H "X-Cisco-Meraki-API-Key: $MERAKI_API_KEY" \
-H "Content-Type: application/json" \
-d '{"name":"lab-01","productTypes":["switch"],"timeZone":"America/Los_Angeles"}' \
https://api.meraki.com/api/v1/organizations/123456/networks
Response: 201 Created with the new network’s id.
Python with the Meraki SDK
import meraki
dashboard = meraki.DashboardAPI(api_key="your-key-here", output_log=False)
orgs = dashboard.organizations.getOrganizations()
for o in orgs:
print(o["id"], o["name"])
nets = dashboard.organizations.getOrganizationNetworks(o["id"])
print(f" {len(nets)} networks")
The SDK handles pagination for you — getOrganizationNetworks fetches every page.
Python with requests only
import os, requests
KEY = os.environ["MERAKI_API_KEY"]
HEADERS = {"X-Cisco-Meraki-API-Key": KEY}
BASE = "https://api.meraki.com/api/v1"
r = requests.get(f"{BASE}/organizations", headers=HEADERS, timeout=10)
r.raise_for_status()
for o in r.json():
print(o["id"], o["name"])
Pagination
Most Meraki endpoints support perPage (max varies per endpoint, 100-1000) and a cursor via startingAfter. The SDK follows cursors for you; with raw requests you check the Link header for rel="next" and loop until it is absent.
Rate limiting
- 10 requests per second per organisation.
- On 429, honour the
Retry-Afterheader (seconds). - The SDK handles backoff automatically.
FAQ
Can I use the Meraki API from on-prem Python? Yes. Meraki Dashboard API is cloud-hosted; your laptop (anywhere) can call it over HTTPS.
My org has multiple API keys. Which does what? Each key is tied to a user’s account and inherits that user’s permissions. For scripts, create a service-account user with least-privilege roles, then generate the key under it.
Where do I find the serial number of a device? In the dashboard: Monitor → Overview → Devices. Programmatically: GET /organizations/{id}/devices or /networks/{id}/devices.
Why do production scripts fail with 429 but mine does not? Scale. Running one script by hand hits rate limits rarely; a scheduled job polling every org every minute will. Build retry-on-429 even for tiny scripts; thank yourself later.
