> ## Documentation Index
> Fetch the complete documentation index at: https://docs.soundchecklive.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Universal Event Format (UEF)

> Canonical JSON schema used by the operator importer and partner feeds

The **Universal Event Format (UEF)** is the canonical shape that all operator data is transformed into before it reaches Soundcheck's normalized tables. The wizard at `/imports` produces one UEF document per import job; partner integrations (n8n CRM sync, custom feeds) and [AI file ingestion](/features/ai/file-ingestion) emit the same shape, so every path shares writer semantics.

If you're just importing a spreadsheet, you don't need to touch UEF directly — the mapping UI hides it. This page is for partners building feeds and for engineers extending the importer.

<Note>
  [AI file ingestion](/features/ai/file-ingestion) produces UEF too. When CheckAI extracts a contract or call sheet, it emits the same document with `source.type: "INGESTION"` — and can additionally propose `ledger_items` (deposits, balances, expenses) and `leads` alongside the events, members, and schedule shown below.
</Note>

***

## Top-level shape

```json theme={null}
{
  "schema_version": "1.0",
  "source": {
    "type": "SPREADSHEET",
    "name": "spring-2026-bookings.xlsx",
    "ingested_at": "2026-05-11T15:00:00Z",
    "import_job_id": "imp_..."
  },
  "events": [
    { /* UEFEvent */ },
    ...
  ]
}
```

* `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; partners use their own identifier.
* `events[]` — the unit the writer iterates over.

***

## UEFEvent

The required fields are minimal — anything else is opt-in.

| Field                        | Type                  | Required | Notes                                                                                                                                                               |
| ---------------------------- | --------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `title`                      | string                | **yes**  | Name of the gig, e.g. "Acme Corp Holiday Party".                                                                                                                    |
| `event_date`                 | string (`YYYY-MM-DD`) | **yes**  | The calendar date the event takes place.                                                                                                                            |
| `external_id`                | string                | no       | Stable identifier from the source system. **Strongly recommended** — drives upsert vs. insert on re-import. Defaults to `{import_job_id}:{row_index}` when omitted. |
| `event_type`                 | string                | no       | Operator-defined category (Wedding, Corporate, Concert, Festival, …).                                                                                               |
| `start_time`                 | string (RFC3339)      | no       | e.g. `2026-06-15T19:00:00-04:00`.                                                                                                                                   |
| `end_time`                   | string (RFC3339)      | no       | Same format as `start_time`.                                                                                                                                        |
| `status`                     | string                | no       | `ACTIVE` (default), `DRAFT`, `TEMPLATE`, `ARCHIVED`.                                                                                                                |
| `currency`                   | string (ISO 4217)     | no       | Defaults to `USD`.                                                                                                                                                  |
| `default_performance_fee`    | decimal               | no       | Numeric, e.g. `500.00`.                                                                                                                                             |
| `payment_terms`              | string                | no       | Free-text, e.g. "Net 30", "On the day".                                                                                                                             |
| `notes`                      | string                | no       | Public notes visible to crew and clients.                                                                                                                           |
| `admin_notes`                | string                | no       | Internal-only notes.                                                                                                                                                |
| `location` / `location_name` | string                | no       | Use these when there's no separate venue column.                                                                                                                    |
| `latitude` / `longitude`     | decimal               | no       | Optional event-level coordinates.                                                                                                                                   |
| `place_id`                   | string                | no       | Google Places ID, when known.                                                                                                                                       |
| `venue`                      | object                | no       | See **UEFVenue** below.                                                                                                                                             |
| `customer`                   | object                | no       | See **UEFCustomer** below.                                                                                                                                          |
| `members[]`                  | array                 | no       | See **UEFMember** below.                                                                                                                                            |
| `schedule_items[]`           | array                 | no       | Timeline rows (load-in, soundcheck, …).                                                                                                                             |
| `metadata`                   | object                | no       | Arbitrary source-system fields preserved for audit.                                                                                                                 |

***

## UEFVenue

| Field                                                | Type            | Notes                                                            |
| ---------------------------------------------------- | --------------- | ---------------------------------------------------------------- |
| `name`                                               | string          | Required when `venue` is present.                                |
| `external_id`                                        | string          | Improves dedup; use the source system's venue ID when available. |
| `address`, `city`, `state`, `postal_code`, `country` | string          |                                                                  |
| `phone_number`, `website`                            | string          |                                                                  |
| `latitude`, `longitude`, `place_id`                  | various         |                                                                  |
| `notes`, `metadata`                                  | string / object |                                                                  |

***

## UEFCustomer

| Field                       | Type            | Notes                                                                                       |
| --------------------------- | --------------- | ------------------------------------------------------------------------------------------- |
| `name`                      | string          | Required when `customer` is present.                                                        |
| `external_id`               | string          | Source-system customer ID.                                                                  |
| `email`, `phone`, `website` | string          |                                                                                             |
| `contacts[]`                | array           | Optional list of contacts on the customer record (name, email, phone, title, `is_primary`). |
| `notes`, `metadata`         | string / object |                                                                                             |

***

## 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.

| Field                     | Type    | Notes                                                          |
| ------------------------- | ------- | -------------------------------------------------------------- |
| `first_name`, `last_name` | string  |                                                                |
| `email`                   | string  | One of `email` or `phone_number` is required for invitation.   |
| `phone_number`            | string  | Same as above.                                                 |
| `position`                | string  | Human-readable; resolved against the organization's positions. |
| `performance_fee`         | decimal | Per-performer override; otherwise the event default applies.   |
| `fee_notes`               | string  |                                                                |
| `call_order`              | integer | `0` = primary, `1+` = backup.                                  |
| `external_id`             | string  | Improves dedup across re-imports.                              |

***

## UEFScheduleItem

| Field        | Type             | Notes                      |
| ------------ | ---------------- | -------------------------- |
| `name`       | string           | Required.                  |
| `start_time` | string (RFC3339) | Required.                  |
| `end_time`   | string (RFC3339) | Optional.                  |
| `order`      | integer          | Defaults to natural order. |
| `notes`      | string           | Optional.                  |

***

## 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 & idempotence

External IDs are the heart of safe re-imports. 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**. That's how 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.

***

## Field catalog

The wizard mapping UI pulls its dropdown from the same field catalog. You can fetch the live catalog from the API:

```bash theme={null}
GET /v1/organizations/{orgId}/imports/catalog
```

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.
