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.
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) emit the same shape so both ingestion paths share 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.
Top-level shape
{
"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:
- By
external_id (when present).
- 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:
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.