Automatically synchronize device inventory from Cisco Meraki Dashboard to Snipe-IT asset management.
This tool seamlessly integrates your network infrastructure data, fetching all devices from your Meraki organization and creating/updating corresponding assets in Snipe-IT. Built for reliability with intelligent caching, rate-limit handling, and comprehensive logging.
✅ Efficient API Usage
- Smart caching minimizes API calls (load categories/models once at startup)
- Batch processing with 0.5s delays to respect rate limits
- Retry logic with exponential backoff for transient failures
✅ Data Integrity
- Automatic category and model creation from Meraki device types
- Idempotent operations—safe to run multiple times
- Deduplication by serial number or asset tag prevents duplicates
✅ Flexible Scheduling
- APScheduler: Python-based scheduler (recommended for all deployments)
- Systemd timer: Native Linux scheduler (recommended for servers)
- Docker container: Containerized deployment
- Manual execution: Run once with
python main.py
✅ Observability
- Structured logging with timestamps and severity levels
- Detailed sync statistics (created, updated, failed counts)
- API call tracking and performance metrics
- Per-device success/failure reporting
┌─────────────────┐
│ Meraki API │
│ (Dashboard) │
└────────┬────────┘
│ [1 API call]
│ Fetch all devices
▼
┌─────────────────────────────────────────────┐
│ Meraki to Snipe-IT Sync │
│ │
│ ┌──────────────────────────────────────┐ │
│ │ 1. Initialize Cache (startup) │ │
│ │ • Load all categories │ │
│ │ • Load all models │ │
│ │ [2-4 API calls total] │ │
│ └──────────────────────────────────────┘ │
│ │
│ ┌──────────────────────────────────────┐ │
│ │ 2. Process Each Device │ │
│ │ • Map Meraki fields to Snipe-IT │ │
│ │ • Look up in cache (no API call!) │ │
│ │ • Create if missing │ │
│ │ • Update if exists │ │
│ │ [1-2 API calls per device] │ │
│ └──────────────────────────────────────┘ │
│ │
│ ┌──────────────────────────────────────┐ │
│ │ 3. Generate Statistics │ │
│ │ • Track success/failure │ │
│ │ • Measure performance │ │
│ │ • Log API usage │ │
│ └──────────────────────────────────────┘ │
└────────┬────────────────────────────────────┘
│
▼
┌─────────────────┐
│ Snipe-IT API │
│ Asset Database │
└─────────────────┘
Meraki Device Data Snipe-IT Asset
─────────────────────────────────────────────────────
name ─────────► name
serial ───┬────► asset_tag
└────► serial (for dedup)
model ┐
├──────► model (auto-create)
productType ┘
mac ──────► notes
networkId ──────► notes
(purchase_date) ──────► purchase_date (if present)
(purchase_cost) ──────► purchase_cost (if present)
status_id: 2 (Ready to Deploy)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Category Hierarchy:
productType (e.g., "Camera", "Switch", "Appliance")
↓ (auto-created if missing)
category (in Snipe-IT)
↓
model (linked to category)
↓
asset (device instance)
For a sync run with 100 devices using 5 unique models across 3 categories:
Without Caching (Old Approach):
- Fetch devices: 1 call
- Per device (100 × 5 ops): 500 calls
- Total: ~501 API calls ❌
With Caching (Current Approach):
- Fetch devices: 1 call
- Initialize cache: 2 calls (categories, models)
- Per device (100 × 1.2 ops): 120 calls
- Total: ~123 API calls ✅ 75% reduction!
- Delay between devices: 0.5 seconds (prevents overwhelming API)
- Rate limit handling: Exponential backoff using
Retry-Afterheader - Max retries: 3 attempts per operation
- Idempotent: Safe to retry without creating duplicates
- Python: 3.11 or later
- APIs: Access to both Meraki and Snipe-IT instances
- Environment:
.envfile with credentials
Create a .env file in the project root:
# Meraki Configuration
MERAKI_API_KEY=your-meraki-api-key-here
ORGANIZATION_ID=your-org-id-here
# Snipe-IT Configuration
SNIPE_IT_API_KEY=your-snipeit-api-token-here
SNIPE_IT_URL=https://snipeit.example.comGet your credentials:
- Meraki API Key: Meraki Dashboard → Account → API → Generate
- Organization ID: Meraki Dashboard → Settings → Organization
- Snipe-IT API Token: Snipe-IT Settings → API → Create New Token
See .env.example for a template.
We provide an automated setup script that handles both development and production deployments:
./setup.shThe script will ask you to choose a setup mode:
- Creates virtual environment in current directory (
./venv) - Perfect for testing and local development
- Run manually with
python main.pyor use APScheduler for scheduling - Next steps after setup:
source venv/bin/activate python main.py
-
Creates virtual environment in
/opt/merakitosnipeit/venv(or custom path) -
Copies all project files to deployment directory
-
Creates
syncersystem user automatically -
Installs systemd service and timer for daily execution at 2:00 AM
-
Survives server reboots
-
Handles sudo access automatically
-
Setup automatically:
- ✓ Copies project files from repo to deployment directory
- ✓ Creates syncer system user for secure execution
- ✓ Creates and configures systemd files
- ✓ Sets proper permissions
-
Final step after setup:
sudo systemctl daemon-reload sudo systemctl enable merakitosnipeit.timer sudo systemctl start merakitosnipeit.timer -
Verify it's running:
sudo systemctl list-timers merakitosnipeit.timer sudo journalctl -u merakitosnipeit.service -n 20
Option B: Using Make (development only, if you have make installed)
make setup
make runOption C: Manual setup (for advanced users)
# Create virtual environment
python3 -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
# Install dependencies
pip install -r requirements.txt
# Run once to test
python main.pyAfter installation, ensure your .env file is configured with your API credentials (see Configuration above), then proceed to Usage.
python main.pyOutput example:
2025-01-15 14:23:45,123 - __main__ - INFO - Starting Meraki to Snipe-IT sync...
2025-01-15 14:23:46,456 - snipe_it - INFO - Initializing entity cache...
2025-01-15 14:23:47,789 - meraki_api - INFO - Successfully fetched 42 devices from Meraki
[1/42] Processing device: Switch-01
✓ Successfully synced device: Switch-01
...
============================================================
SYNC SUMMARY
============================================================
Total devices processed: 42
✓ Successful: 41
✗ Failed: 1
→ Created: 5
↻ Updated: 36
Duration: 38.45 seconds
============================================================
Run every hour:
python scheduler.pyWith custom interval (every 30 minutes):
python scheduler.py --interval 30With cron expression (run at noon and midnight):
python scheduler.py --cron "0 0,12 * * *"Run once and exit (useful for testing):
python scheduler.py --run-onceInstall the service and timer:
# Copy files to system
sudo cp merakitosnipeit.service /etc/systemd/system/
sudo cp merakitosnipeit.timer /etc/systemd/system/
# Create user and directory
sudo useradd -m -s /bin/bash syncer
sudo mkdir -p /opt/merakitosnipeit
sudo cp -r ./* /opt/merakitosnipeit/
sudo chown -R syncer:syncer /opt/merakitosnipeit
# Install dependencies
cd /opt/merakitosnipeit
sudo -u syncer pip install -r requirements.txt
# Enable and start timer
sudo systemctl daemon-reload
sudo systemctl enable merakitosnipeit.timer
sudo systemctl start merakitosnipeit.timer
# Check status
sudo systemctl status merakitosnipeit.timer
sudo journalctl -u merakitosnipeit.service -fBuild the image:
docker build -t merakitosnipeit:latest .Run with APScheduler (hourly):
docker run -d \
--name merakitosnipeit \
--env-file .env \
--restart unless-stopped \
merakitosnipeit:latest \
python scheduler.py --interval 60Run once:
docker run --rm --env-file .env merakitosnipeit:latest python main.pypytest -vControl logging detail via environment variable:
LOGLEVEL=DEBUG python main.py # Verbose logging
LOGLEVEL=WARNING python main.py # Only warnings and errorsTest without making API calls:
python main.py --dry-runIf you see "Rate limit exceeded" messages:
- Increase the delay between devices in
main.py(line 141) - Reduce the sync frequency (increase interval)
- Check Snipe-IT API rate limits in admin settings
Verify in Meraki Dashboard:
- Organization ID is correct
- API key has read permissions
- Network has devices
- Double-check credentials in
.env - Verify Snipe-IT URL includes protocol (https://)
- Ensure API tokens haven't expired
Typical sync times (per 100 devices):
- Cache initialization: 2-3 seconds
- Meraki fetch: 3-5 seconds
- Processing: 50-120 seconds (depends on network and API latency)
- Total: ~1-2 minutes
Factors affecting performance:
- Number of devices
- Number of unique models/categories
- Network latency to APIs
- Snipe-IT server performance
| Scenario | Recommended | Reason |
|---|---|---|
| Linux Server | Systemd Timer | Native, reliable, no overhead |
| Cloud VM | APScheduler | Portable, easy to containerize |
| Kubernetes | CronJob | Native orchestration |
| Docker Desktop | APScheduler | Simple, self-contained |
| Testing | Manual (python main.py) |
Quick feedback loop |
- Modular: Separate Meraki, Snipe-IT, and orchestration logic
- Idempotent: Safe to run multiple times—no side effects
- Cacheable: Minimizes API calls with smart caching
- Resilient: Retries transient failures, continues on per-device errors
- Observable: Comprehensive logging and statistics
- Async API calls for faster processing
- Database backend for state persistence
- Multi-organization support
- Custom field mapping configuration
- Webhook notifications on sync completion
- Prometheus metrics endpoint
MIT
For issues or questions:
- Check Troubleshooting section
- Review logs:
grep ERROR /var/log/sync.log - Run in debug mode:
LOGLEVEL=DEBUG python main.py - Open an issue on GitHub