1. Wiki
  2. Before It's Gone
  3. Import & Export

Import & Export Format

Before It's Gone can export your inventory to JSON or CSV, and import from either format. This page documents the exact structure expected for each.

JSON

Exporting

The app exports a single JSON object with three top-level keys:

{
  "version": 1,
  "exportedAt": "2026-05-18T14:30:00.000Z",
  "items": [ ... ]
}
KeyTypeDescription
versionnumberSchema version. Currently always 1.
exportedAtstringISO 8601 timestamp of when the export was created.
itemsarrayArray of inventory item objects (see below).

Item object

FieldTypeNotes
idstringUUID. Preserved on re-import: re-importing the same export will overwrite the existing record rather than duplicate it.
namestringDisplay name of the item.
quantitynumberMust be a positive integer ≥ 1.
locationstringOne of "fridge", "freezer", "pantry".
barcodestring | nullRaw barcode string, or null if none was scanned.
expiresAtstringISO 8601 timestamp of the expiry date.
shelfLifeDaysnumberShelf life in days, stored at creation time.
createdAtstringISO 8601 timestamp.
updatedAtstringISO 8601 timestamp.
categorystring | nullFree-text category label, or null.
depletionThresholdnumber | nullLow-stock alert threshold (quantity), or null if unset.
tagsstring[]Array of tag strings. Empty array if none.
recurringbooleanWhether the item auto-restocks when depleted. Optional; defaults to false.
restockQuantitynumber | undefinedQuantity to restock to when recurring is true. Optional.

Full example

{
  "version": 1,
  "exportedAt": "2026-05-18T14:30:00.000Z",
  "items": [
    {
      "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
      "name": "Whole Milk",
      "quantity": 2,
      "location": "fridge",
      "barcode": "5000112637922",
      "expiresAt": "2026-05-25T23:59:59.000Z",
      "shelfLifeDays": 10,
      "createdAt": "2026-05-15T08:00:00.000Z",
      "updatedAt": "2026-05-15T08:00:00.000Z",
      "category": "dairy",
      "depletionThreshold": 1,
      "tags": ["organic", "fridge-door"],
      "recurring": true,
      "restockQuantity": 2
    },
    {
      "id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
      "name": "Penne",
      "quantity": 3,
      "location": "pantry",
      "barcode": null,
      "expiresAt": "2027-12-31T23:59:59.000Z",
      "shelfLifeDays": 730,
      "createdAt": "2026-05-10T10:00:00.000Z",
      "updatedAt": "2026-05-10T10:00:00.000Z",
      "category": "pasta",
      "depletionThreshold": null,
      "tags": [],
      "recurring": false
    }
  ]
}

Importing

The importer reads the items array from inside the { version, exportedAt, items } envelope. Items missing an id or name are silently skipped. If you re-import a file that was previously exported, existing items with matching id values are overwritten in place rather than duplicated.

Tip: JSON import is best for full backups and restores. Use CSV import when adding items from a spreadsheet.

CSV

Exporting

The exported CSV uses the following fixed column order:

name,quantity,location,barcode,expiresAt,category,tags,shelf_life_days,depletion_threshold,createdAt
  • Values that contain commas are double-quoted.
  • barcode, category, shelf_life_days, and depletion_threshold are empty strings when not set.
  • expiresAt is a date-only string (YYYY-MM-DD); createdAt is a full ISO 8601 timestamp.
  • tags is a semicolon-separated list (e.g. organic;bulk); empty string if none.
Note: CSV export omits id, recurring, restockQuantity, and per-item photos. Use JSON export for a complete, lossless backup.

Example export

name,quantity,location,barcode,expiresAt,category,tags,shelf_life_days,depletion_threshold,createdAt
"Whole Milk",2,fridge,5000112637922,2026-05-25,dairy,organic;fridge-door,10,1,2026-05-15T08:00:00.000Z
Penne,3,pantry,,2027-12-31,pasta,,730,,2026-05-10T10:00:00.000Z
"Free-range Eggs, 6pk",6,fridge,5010029005120,2026-06-01,eggs,,21,2,2026-05-18T09:00:00.000Z

Importing

The CSV importer accepts any column order and a wider set of column names. Column headers are case-insensitive.

Column reference

Column nameRequiredTypeNotes
nameYesstringItem display name. Rows with an empty name are skipped.
expires_atYesstringExpiry date. See date formats below. Also accepted as expiresat (no underscore).
locationYesstringMust be exactly fridge, freezer, or pantry (case-sensitive). Rows with any other value are skipped.
quantityNonumberDefaults to 1 if missing or non-numeric. Always at least 1.
barcodeNostringLeave empty if none.
categoryNostringFree-text category label.
shelf_life_daysNonumberShelf life in days. If omitted, calculated from expires_at minus today. Always at least 1.
tagsNostringSemicolon-separated list of tags, e.g. organic;bulk;fridge-door.
depletion_thresholdNonumberLow-stock alert threshold. Leave empty for none.

Date formats

The importer accepts all of the following formats for expires_at. The time portion is always normalised to end-of-day UTC automatically — you never need to write a timestamp yourself.

FormatExample
YYYY-MM-DD2026-06-01
YYYY/MM/DD or YYYY.MM.DD2026/06/01
MM/DD/YYYY or M/D/YYYY6/1/2026
MM-DD-YYYY or M-D-YYYY6-1-2026
Full ISO timestamp2026-06-01T23:59:59.000Z
Month name, day firstJune 1, 2026 · Jun 1 2026
Month name, day last1 June 2026 · 1 Jun 2026
Note: Slash and dash formats with a 4-digit year at the end (e.g. 6/1/2026) are treated as MM/DD/YYYY. Use YYYY-MM-DD to avoid ambiguity.

Rows that are skipped

A row is skipped (counted in the "X rows skipped" status message) if:

  • name is empty or missing
  • expires_at / expiresat is empty, missing, or not a parseable date
  • location is not one of fridge, freezer, pantry
  • The entire row throws an unexpected parse error

Skipped rows do not cause the import to fail; the rest of the file continues to be processed.

Example import file

name,quantity,location,expires_at,barcode,category,shelf_life_days,tags,depletion_threshold
Whole Milk,2,fridge,2026-05-25,5000112637922,dairy,10,organic;fridge-door,1
Penne,3,pantry,2027-12-31,,pasta,730,,
"Free-range Eggs, 6pk",6,fridge,2026-06-01,5010029005120,eggs,21,,,2
Frozen Peas,4,freezer,2027-03-01,,vegetables,365,bulk,
Tip: When creating a CSV by hand or from a spreadsheet, use YYYY-MM-DD for expires_at and separate multiple tags with semicolons (not commas).

Format comparison

JSON exportCSV exportJSON importCSV import
id✅❌✅ preserved❌ new UUIDs assigned
name✅✅✅✅
quantity✅✅✅✅
location✅✅✅✅
barcode✅✅✅✅
expiresAt / expires_at✅ full ISO✅ date only✅✅
shelfLifeDays✅✅ (shelf_life_days)✅✅ (shelf_life_days)
category✅✅✅✅
tags✅✅ semicolon-separated✅✅ semicolon-separated
depletionThreshold✅✅ (depletion_threshold)✅✅ (depletion_threshold)
recurring / restockQuantity✅❌✅❌
photo✅❌✅❌
createdAt / updatedAt✅createdAt only✅ preserved❌ set to import time

For a lossless round-trip (export → edit → re-import), always use JSON. CSV export omits id, recurring, restockQuantity, and photos. CSV import creates new item IDs and timestamps.

Barcode import

The Import barcodes (.txt) button in the Data section accepts a plain text file with one barcode per line:

5000112637922
5010029005120
3017620429484

For each barcode the app:

  1. Queries Open Food Facts for the product name, category, and nutritional info.
  2. Creates a new inventory item using your default shelf life and default storage location from Settings.
  3. Saves the nutritional profile (kcal/100g, allergens) to the barcode profile store.

A progress bar tracks enrichment. Barcodes that Open Food Facts does not recognise are still imported, using the raw barcode string as the item name.

Note: Barcode import always creates new items with new UUIDs. It does not deduplicate against existing inventory.
Last updated: 2026-10-04 AetherAssembly/Before-Its-Gone → License: GNU AGPLv3