Skip to main content
Universal Event Format (UEF) is the JSON shape every import path lands in before normalized tables are written. The wizard on Settings → Organization → Imports (/settings/organization/imports) builds one UEF document per job. Partner integrations (n8n CRM sync, custom feeds) and AI file ingestion emit the same shape, so every path shares writer semantics. If you’re just importing a spreadsheet, start with Import your data and start running. You don’t need to touch UEF directly. This page is for partners building feeds and for engineers extending the importer.
AI file ingestion, a CheckAI Private Preview feature for existing beta testers only, produces UEF too. When CheckAI extracts a contract or call sheet, it emits the same document with source.type: "INGESTION", and can also propose ledger_items (deposits, balances, expenses) and leads alongside the events, members, and schedule shown below.

Top-level shape

  • schema_version: bump only when the shape changes in a way that older mappings would not survive. Current value: 1.0.
  • source.type: "SPREADSHEET" or "PASTE" for the wizard; "INGESTION" for AI file ingestion; "EXPORT" for a workspace export. Partners use their own identifier.
  • events[]: the unit the writer iterates over.

UEFEvent

Required fields are minimal. Everything else is opt-in.

UEFVenue


UEFCustomer


UEFMember

One crew member on the event. To produce an invitation, a member must have either email or phone_number. Rows without a contact channel are skipped at write time.

UEFScheduleItem


Datetime conventions

  • event_date: YYYY-MM-DD (no time component).
  • start_time, end_time, schedule_items[].start_time/end_time: RFC3339 with offset, e.g. 2026-06-15T19:00:00-04:00.
  • source.ingested_at: RFC3339 UTC.

Identity and idempotence

External IDs keep re-imports safe. The writer matches in this order:
  1. By external_id (when present).
  2. By natural key: (title, event_date) for events, name (case-insensitive, scoped to the organization) for venues and customers.
When both fields are present, external_id wins. Renaming an event in the source system stays linked instead of becoming a duplicate. Invitations are deduped at the database level by partial unique indexes on (eventId, lower(email)) and (eventId, phoneNumber), with ON CONFLICT DO NOTHING. Re-running the same import is always safe. Spreadsheet Crew import still requires email on each roster row. That is separate from UEF member invitation identity (email or phone).

Field catalog

The wizard mapping UI pulls its dropdown from the same field catalog. Fetch the live catalog from the API:
This returns one entry per mappable path (e.g. events[].event_date, events[].venue.name, events[].members[].email) with type, required flag, and a short description. The catalog is the source of truth. If it isn’t listed there, the importer can’t write to it.