Bulk import lets you onboard large batches of contacts at once — no manual data entry required. Upload a spreadsheet, map its columns to the Contacts DB fields, preview the first ten rows, and run the import. The importer validates each row, skips duplicates automatically, and reports a summary when it is finished.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/0m1n3m/contacts-db/llms.txt
Use this file to discover all available pages before exploring further.
The
contact_category and relationship_status fields are required for every row. Any row missing either of these values is counted as invalid and skipped.Supported File Formats
| Format | Extension | Notes |
|---|---|---|
| CSV | .csv | Comma, semicolon, or tab-delimited |
| TSV / text | .txt | Tab-delimited plain text |
| Excel | .xlsx, .xls | First sheet is used |
\t, ,, and ; on the first line and picking the one that appears most often.
Import Process
Navigate to the import page
Go to
/contacts/import. This page is protected by the role:admin,editor middleware — only admins and editors can access it.Upload your file
Choose a
.csv, .txt, .xlsx, or .xls file up to 10 MB. After submitting the upload form the server stores the file temporarily and parses it. For CSV and TSV files the delimiter (comma, semicolon, or tab) is detected automatically by scanning the first line. For Excel files the first sheet is read using the Maatwebsite Excel library. UTF-8 BOM characters are stripped from the first header cell automatically.Map columns
The import mapping page (
POST /contacts/import/preview) shows a list of all contact fields alongside a dropdown for each one. Select which column from your spreadsheet corresponds to each database field. The system performs auto-mapping before you arrive on this page — see Column Mapping below for the rules.Preview the data
The mapping page displays the first 10 data rows of your file rendered according to the current mapping. Use this to verify that values appear in the correct fields before committing.
Run the import
Click Import to submit the mapping form as a
POST to /contacts/import/run. The server iterates over all data rows, validates each one, runs deduplication checks, and saves new contacts. The temporary file is deleted afterwards. You are then redirected to the contacts list with a summary flash message.Column Mapping
On the mapping screen you assign each contact field to a column from your spreadsheet. Fields marked with* are required — every row that lacks a value for these fields will be skipped.
| Contact DB field | Label | Required |
|---|---|---|
contact_category | Contact category | ✅ * |
relationship_status | Relationship status | ✅ * |
use_for_events | Use for events | No |
potential_speaker | Potential speaker | No |
organisation_name | Organisation name | No |
first_name | First name | No |
last_name | Last name | No |
job_title | Job title | No |
emails | Emails (list) | No |
phones | Phones (list) | No |
country | Country (ISO code) | No |
organisation_types | Organisation types (list) | No |
keywords | Keywords (list) | No |
relevant_project_programme | Relevant project / programme | No |
expertise_speaking_topics | Expertise / speaking topics | No |
stakeholder_type | Stakeholder type | No |
comment | Comment | No |
Auto-mapping
Before presenting the mapping form, the server normalises every header from your file (lowercased, spaces and slashes replaced with underscores, special characters removed) and attempts to match it to a contact field. If your column header matches a field name exactly, or matches one of the aliases in the table below, the mapping is pre-filled automatically.| Spreadsheet header (normalised) | Maps to field |
|---|---|
email, e_mail | emails |
phone, telephone, tel | phones |
organisation, organization, org | organisation_name |
organization_types, org_types | organisation_types |
expertise, speaking_topics | expertise_speaking_topics |
project_programme | relevant_project_programme |
Multi-Value Columns
Theemails, phones, organisation_types, keywords, and expertise_speaking_topics fields store arrays. The importer accepts several cell formats for these columns:
[ and decodes to a valid JSON array, each element becomes an array item. Otherwise it looks for ;, then ,, then | as delimiters and splits on the first one it finds. If none are present, the entire cell is treated as a single-element array. Each resulting item is trimmed and blank items are discarded.
Deduplication
The importer checks each incoming row against existing contacts before inserting. Rows identified as duplicates are skipped and counted in the result summary.Primary check — email match
If the row contains one or more valid email addresses (validated withFILTER_VALIDATE_EMAIL), the importer queries the contacts table for any existing contact whose emails JSON array contains any of those addresses (case-insensitive). If a match is found, the entire row is treated as a duplicate and skipped.
Fallback check — name and organisation match
If the row has no valid email addresses, the importer falls back to matching on the combination oforganisation_name, first_name, and last_name (all compared case-insensitively). If all three values match an existing contact, the row is skipped.
The fallback check only runs when no valid email is present. Rows with no email and no name/organisation data are not deduplicated — they will always be inserted if they pass validation.
Import Result
After the import completes you are redirected to the contacts list (/contacts) with a flash message in the following format:
| Counter | Meaning |
|---|---|
| Imported | Rows successfully saved as new contacts |
| Skipped invalid | Rows missing contact_category or relationship_status, or rows that threw an unexpected error during save |
| Skipped duplicates | Rows that matched an existing contact via email or name/organisation fallback |
Exporting Contacts
Export is available to all authenticated users — no special role is required.Select contacts on the list page
Use the row checkboxes in the contacts list at
/contacts to select the records you want to export. The toolbar shows the current count: Export selected (CSV) (N). Only admins see the checkboxes on their own; editors and viewers also see checkboxes next to the export button.- Is named
contacts-selected-YYYYMMDD-HHmmss.csv - Is encoded as UTF-8 with BOM (
\xEF\xBB\xBF) so Microsoft Excel opens it without encoding issues - Contains all 20 columns:
id,contact_category,relationship_status,use_for_events,potential_speaker,organisation_name,first_name,last_name,job_title,emails,phones,country,organisation_types,keywords,relevant_project_programme,expertise_speaking_topics,stakeholder_type,comment,created_at,updated_at - Exports
use_for_eventsandpotential_speakeras1or0 - Exports JSON array columns (
emails,phones,organisation_types,keywords,expertise_speaking_topics) as JSON strings, for example["a@b.com","c@d.com"]
Overview & Data Model
Full reference for every field, type, and access-control rule in the Contacts module.
Managing Contacts
Create, edit, search, and delete contacts individually or in bulk.