Skip to main content

Bulk Records — Import & Export

The Team Certifications page can export every record in your agency to a CSV, and import a CSV back. Same flow handles certifications, background checks, training records, vaccinations, etc.

This is most useful for:

  • Backups — periodic full export of agency records.
  • Bulk seed — when you onboard a new agency or migrate from another system, hand-build a CSV and import.
  • Bulk update — export, edit a column in Excel, re-import; matched rows update in place.

The CSV is metadata only. Supporting documents (PDFs, photos) are not included; see Supporting documents below.

The record lifecycle

Every record moves through three states. The state controls who can edit what.

StateSet byWho can editWhat can be edited
Editable (unlocked)Default on creationThe record's owner (the named member) and admins / training coordinatorsAll fields
Validated (still unlocked)Agencies that don't require approval, on creationSame as Editable — owner can keep editingAll fields
LockedAdmin runs Validate on a pending record, or clicks the manual lock buttonAnyone with access can read; only notes can be editedNotes only

Two important properties of this model:

  1. A record is editable until it's deliberately locked. Auto-validation (in agencies that don't require approval) does not lock the record. The owner can still attach a file, fix a typo, or replace a wrong value.
  2. Locking is one-way through the UI. Admins can re-unlock from the cert detail modal if needed.

Exporting

From Team Certifications → Export → CSV. Runs as a background task; you'll see a "Comprehensive backup exported" toast when ready.

The exported file is named Team_Certifications_<timestamp>.csv and contains every record where the subject is a person in your agency.

CSV columns

ColumnWhat it isBehaviour on import
Record IDThe internal UUID of the recordOptional. When present, the import matches the CSV row to that exact record (rename-safe). When blank, import falls back to matching by (member email, record name, record type). Leave blank for fresh imports so the import creates new records instead of trying to update non-existent ones.
Record TypeCERTIFICATION, BACKGROUND_CHECK, MEDICAL_RECORD, VACCINATION, TRAINING_RECORD, LICENSE, INSURANCE, OTHERRequired.
Subject TypeAlways PERSON for member recordsRequired.
Template NameThe name of the agency Record Template, if the record was created from oneOptional. If present, the import looks up that template by name; if not found, the record is still created but template-linked fields (lock flags, notification timing) won't apply.
User EmailThe agency member's login emailRequired. Lookup is case-insensitive but the user must already exist in the agency. Rows with unknown emails are skipped with an error.
User First Name / User Last NameDisplay onlyIgnored on import — the user is identified by email.
Record NameThe cert / record nameRequired.
DescriptionFree textOptional.
Issuing OrganizationWho issued itOptional.
External Record IDThe ID printed on the certificate, if any (different from Record ID above)Optional.
Issue DateYYYY-MM-DDRequired.
Expiry PeriodMonths until expiration. Falls back to the template's value if blank.Optional.
StatusACTIVE, EXPIRED, etc. — recalculated from Issue Date + Expiry Period on save.Ignored — the system computes it.
Validation Statusvalid, pending, invalidOptional. Defaults to pending when blank or unrecognized. Setting valid does NOT lock the record. The value affects what an admin can do next — see Validation Status and the import below.
Training Hours, Location, Instructor, Certification Level, NotesFree-text / numeric metadataOptional.
First / Second / Third / Final Notification DaysDays before expiration to send each notification. Falls back to the template's values if blank.Optional.
Type Specific DataJSON blob for record-type-specific fields like check_type for Background ChecksOptional.
Created By EmailAudit trailIgnored on import — the importer's email is recorded.

Importing

From Team Certifications → Import. Pick a CSV file; the import runs in the background and shows a results modal when done.

What the import does, row by row

  1. Find the user by User Email (case-insensitive). Skip the row with an error if not found.
  2. Check for an existing record:
    • If Record ID is present and matches a record in your agency → update that record.
    • Otherwise, look for an existing record with the same (user, Record Name, Record Type). If found → update.
    • Otherwise → create a new record.
  3. Apply the CSV's values to the record. The owner can edit anything except notes after this — unless the record is already locked.
  4. Files are not affected. Existing files on existing records survive untouched.

Import results

The modal reports:

  • Created — new records added.
  • Updated — existing records where one or more fields changed.
  • Errors — per-row error messages (e.g. "Row 47: User with email orphan@example.com not found in agency"). Other rows in the same file still import normally.

Validation Status and the import

The import never locks records on its own — locking is always a deliberate admin action (Validate or the manual Lock button). But the value you put in Validation Status controls what the admin can do next.

Validation Status in CSVImported record stateWhat admins see
Blank, or pendingpending, unlockedValidate button is available. Clicking it flips the record to valid AND auto-locks it. This is the normal review flow.
validvalid, unlockedValidate button is unavailable (record reports "already validated"). To lock, admin uses the manual Lock button. Owner can edit until the lock fires.
invalidinvalid, unlockedValidate button is available — admin re-validates → record flips to valid and auto-locks.

Recommendation: for a fresh agency seed or a normal bulk import, leave Validation Status blank. Records arrive as pending, the admin reviews each one through the normal Validate flow, and the lock happens at the moment they sign off — same as records created through the wizard.

Pre-marking rows as valid is appropriate when you're migrating from another system where approvals already happened. In that case the records skip the review step but do not lock automatically; lock them manually if you want them sealed.

Other ways to keep imports clean

  • Don't worry about Record ID. If you're seeding fresh records, leave the column blank (or omit it entirely) and the import will create new rows.
  • Status and Created By Email are read-only. The system computes Status from issue date + expiry; the importer's email is recorded as Created By automatically. Anything you put in those columns is ignored.

Round-trip update workflow

The most reliable bulk-update pattern:

  1. Export the CSV from Team Certifications.
  2. Open in Excel; edit only the cells you want to change.
  3. Re-import. The Record ID column ensures every row matches the original record; only your edits are applied.

This avoids the "two records with the same name got collapsed" edge case that can happen when matching by name alone.

Supporting documents

The CSV does not include file attachments. To add a supporting document for a record:

  1. Open the record from Team Certifications (or the member's own My Certifications page).
  2. Use the Edit action.
  3. Drag-and-drop or pick a file in the Supporting Documents section.
  4. Save.

This works whether the record was created via the wizard or imported from a CSV. The only thing that prevents file uploads is a locked record (lock = admin signed off).

For agencies that need full backup including files, contact support — file-bundle export is on the roadmap but not yet built.

Permissions summary

ActionRequired permission
Export CSVAdmin or Training Coordinator
Import CSVAdmin or Training Coordinator
Edit a record (when unlocked)The record's owner, or Admin / Training Coordinator
Edit notes onlyAnyone with view access
Validate a pending recordAdmin or Training Coordinator
Lock a record manuallyAdmin or Training Coordinator
Unlock a locked recordAdmin