How to Import Assets into Snipe-IT: Complete CSV Guide
Snipe-IT provides a built-in CSV importer that lets you bulk-create or update assets via a three-step wizard or programmatically using the abstract Importer class and concrete AssetImporter.
Snipe-IT is the open-source IT asset management system maintained by grokability. Whether you are migrating from a spreadsheet or conducting regular bulk updates, understanding how to import assets into Snipe-IT requires familiarity with its three-tier import architecture that handles everything from file validation to database transactions.
Snipe-IT Import Architecture Overview
The import workflow is orchestrated by three core components working in sequence:
ImportController– Located atapp/Http/Controllers/Api/ImportController.php, this handles the HTTP request for CSV upload, validates MIME types and encoding, stores the file, and creates anImportrecord.Importer(Livewire component) – Found inapp/Livewire/Importer.php, this powers the UI wizard that guides users through selecting the import type, mapping columns, previewing rows, and triggering processing.Importer(abstract class) – Defined inapp/Importer/Importer.php, this implements the low-level CSV parsing usingLeague\Csv\Reader, row-by-row handling, transaction logic, and database insertion.
Step-by-Step Import Workflow
1. Upload CSV Files
The process begins when the user submits a CSV via the UI (resources/views/livewire/importer.blade.php), which posts to ImportController::store(). The controller validates the MIME type, optionally re-encodes non-UTF-8 files, and stores the upload under storage/app/private/uploads/imports. It then creates a record in the imports table using App\Models\Import to track metadata such as the original filename and file size.
2. Select Import Type
After upload, the Livewire component reads the stored Import record and presents a wizard interface. The user selects the target entity via the $typeOfImport property. For asset imports, you choose Asset, which instantiates the concrete AssetImporter class (extending the abstract Importer) to handle the specific validation rules for asset models.
3. Map CSV Columns to Model Fields
Column mapping relies on Importer::$defaultFieldMap, an array that maps every possible CSV heading to its canonical model attribute (e.g., asset_tag, serial, model). The UI constructs dropdowns for required fields using the $required_field_model_map array, which links the target model’s validation rules to the mapping interface. This ensures that mandatory fields like asset_tag cannot be left unmapped.
4. Preview Before Processing
Before committing changes, the importer displays the first N rows defined by Importer::PREVIEW_ROW_LIMIT. This preview step lets you verify that the column mapping correctly interprets your data, catching issues like misaligned headers or encoding errors before database insertion begins.
5. Process the Import
When you click Process, the Livewire component delegates to the concrete importer (e.g., AssetImporter). The import runs inside a database transaction (DB::transaction) to ensure atomicity. The abstract class iterates through CSV rows, skipping blank rows using the rowIsBlank() method, and creates or updates records based on the $updating flag. Progress streams back to the UI via the $progress and $message properties.
Configuration Options
The importer respects several settings that modify behavior:
- Full Multiple Company Support – When the
full_multiple_companies_supportsetting is enabled, the import can filter by or assign acompany_idcolumn to ensure assets land in the correct company scope. - Backup Option – The wizard can request a pre-import backup; the controller’s
process()method toggles$backupRequestedto trigger a database dump before processing begins. - Custom Fields – Custom fields are cached in the
$customFieldsproperty and populated automatically when the CSV contains matching headings, allowing dynamic attribute assignment without manual schema updates.
Programmatic Asset Import
You can run asset imports outside the UI—useful for scheduled jobs or custom Artisan commands. The following example demonstrates loading a CSV and running the import directly:
use App\Importer\Importer;
use League\Csv\Reader;
// 1️⃣ Load CSV (string or file path)
$csvPath = storage_path('app/private/uploads/imports/my_assets.csv');
$csv = Reader::createFromPath($csvPath, 'r');
// 2️⃣ Instantiate the concrete importer (AssetImporter extends Importer)
// The concrete class lives in `app/Importer/AssetImporter.php`
$importer = new \App\Importer\AssetImporter($csvPath);
// 3️⃣ Optional: customize field mapping if your headings differ
$importer->fieldMap = [
'asset_tag' => 'Tag',
'serial' => 'Serial Number',
'model' => 'Model Name',
// …other mappings…
];
// 4️⃣ Run the import
$importer->import(); // processes the whole file inside a transaction
Key Source Files Reference
| File | Purpose |
|---|---|
app/Http/Controllers/Api/ImportController.php |
Receives uploads, validates encoding, stores files, creates Import models. |
app/Livewire/Importer.php |
Livewire component powering the wizard UI, field mapping, and progress feedback. |
app/Importer/Importer.php |
Abstract base class containing CSV parsing, transaction handling, and rowIsBlank() logic. |
app/Importer/AssetImporter.php |
Concrete implementation extending Importer for asset-specific validation. |
app/Models/Import.php |
Eloquent model representing uploaded import files and metadata. |
config/importer.php |
Configuration defaults for import behavior, chunk sizes, and backup options. |
Summary
- Snipe-IT imports assets via a robust CSV pipeline using
ImportControllerfor uploads, LivewireImporterfor the UI, and an abstractImporterclass for database logic. - The workflow requires uploading a CSV, selecting the Asset type, mapping columns using
$defaultFieldMap, previewing rows, and processing within a database transaction. - Configuration options include multi-company support, pre-import backups, and automatic custom field mapping.
- Programmatic imports use
AssetImporterextending the abstractImporter, supporting custom field maps and running insideDB::transaction.
Frequently Asked Questions
What file format does Snipe-IT require for asset imports?
Snipe-IT requires CSV files. The ImportController validates MIME types and automatically re-encodes files to UTF-8 if necessary. Store your data with standard comma separators and ensure your first row contains headers that map to Snipe-IT fields like asset_tag and serial.
Can I update existing assets via CSV import instead of creating new ones?
Yes. The abstract Importer class supports an $updating flag. When enabled, the importer identifies existing records (typically by asset_tag or another unique key) and updates their attributes rather than creating new database rows. This is handled inside the DB::transaction block to ensure data integrity.
Where are uploaded import files stored in Snipe-IT?
Uploaded CSVs are stored in storage/app/private/uploads/imports according to the ImportController::store() method. The App\Models\Import Eloquent model tracks the file path, original name, and upload metadata in the imports database table, allowing the Livewire component to retrieve the file during the mapping and preview phases.
How do I handle custom fields when importing assets?
Custom fields are cached in the $customFields property during initialization. If your CSV contains column headings that match the names of custom fields defined in your Snipe-IT instance, the importer automatically maps those values to the corresponding custom field entries without requiring manual schema configuration.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →