Skip to content

Reading the columns

How to navigate 342 columns without reading 342 rows of documentation.

Column families

Every column belongs to a family identified by its prefix. Here is the whole ticket row, by family:

FamilyColumnsWhat it describes
TicketOwnerInfo*107Your own custom registration fields — see below
Ticket*41The ticket itself: number, status, validity, prices, wallet links
TicketOwner*40The person who attends: name, address, contact, company, function
Buyer*33The person who paid
Sale*16The purchase transaction, including SaleUtm* campaign parameters
Fairevent*16The event edition: name, year, dates, numbers
Legitimation*12Proof presented for a restricted article, and its validity window
UpsellingSource* / Upselling*10Upgrade origin and value uplift
CrossSellingSource* / CrossSelling*10Cross-sell origin and value uplift
PromotionCode*8Discount or access code applied
Article*8What was sold, including the badge category
Exhibitor*6Which exhibitor issued the ticket, where applicable
FairBrand*4The event series the edition belongs to
Currency*4Currency of the monetary columns
Payment*4How it was paid
Mandator*, Cart*, Third*3Tenant, cart reference, third-party registration state

TicketUsages follows the same convention with a Usage-flavoured core (Timestamp, Entrance*, Location*, IsEntry, IsExit, IsFirstOf*) plus a repeated slice of ticket, article and event columns so common questions need no join.

The custom registration fields

Almost a third of the ticket row — TicketOwnerInfo2TicketOwnerInfo100 and TicketOwnerInfoLookup1TicketOwnerInfoLookup8 — is not a fixed schema. These are the free-form fields your own registration forms write into.

What they areSlots filled by your registration configuration
Labels in $metadataGeneric: "Ticket owner: Info 47"
MeaningDefined by your setup, not by us
NumberingStarts at TicketOwnerInfo2; there is no TicketOwnerInfo1

You have to supply the mapping. We cannot label these for you, because what TicketOwnerInfo47 holds depends on how your registration form was configured. Ask whoever configured it for the field mapping, record it in your warehouse as a lookup, and rename the columns as you stage them. A staging model that renames TicketOwnerInfo47 to visitor_job_role is the difference between a usable warehouse and an unusable one.

Most extracts load only the handful of these that their forms actually use. Loading all 107 is rarely useful.

Types and how they behave

Type in $metadataNotes
Edm.Int32 / Edm.Int64Ids and counts.
Edm.StringText — including the status columns, see below.
Edm.BooleanFlags. Some are nullable, so treat null as its own case.
Edm.DecimalMoney, with precision 14 and scale 6. Load as decimal, never float.
Edm.GuidThe *UniqueId columns.
Edm.DateTimeOffsetPoints in time, with an offset.
Edm.Date / no-offset date-timesCalendar dates and internal timestamps — see the warning below.

Status columns are strings holding tokens

TicketStatusType, SaleStatus, ArticleType and their relatives are Edm.String carrying UPPER_SNAKE_CASE tokens such as ASSIGNED, PAID or SERVICE_FEE. They were numeric enums once; the hub converted them to text deliberately, so that consumers see a readable label instead of an integer whose meaning lives in someone else's source code.

Most of them have a closed, documented value setColumn values lists every one, and marks the handful that are pass-through columns whose values come from the source system rather than from a fixed list.

Filter them as ordinary strings: ?$filter=SaleStatus eq 'COMPLETED'.

Time zones — the one that silently corrupts reports

Two different kinds of temporal column exist, and they must be handled differently:

KindColumnsHandle by
Offset-aware instantsTicketSoldAt, TicketUsedAt, TicketRegisteredAt, TicketAssignedAt, SaleTimestamp, PaymentTimestamp, TicketCancelledOn, TicketShippedOn, FaireventStartDate, FaireventEndDate, LegitimationValidFrom/ValidTo, PromotionCode* timestamps, and Timestamp on usagesConverting to whatever zone you report in. These carry an offset and are unambiguous.
Plain dates and internal timestampsTicketOwnerBirthDate, TicketOwnerLastActionOn, LastRefreshedAtDo not time-zone convert these.

TicketOwnerBirthDate is a calendar date, not an instant. Converting it across zones shifts birthdays by a day and quietly corrupts every age bracket you compute. Load it as a date type, not a timestamp.

LastRefreshedAt and TicketOwnerLastActionOn carry no offset either. Use LastRefreshedAt only as an opaque watermark for incremental loading — compare it against the last value you saw, and do not present it to users as a local time.

There is no fair-local time column. The event's own time zone is not exposed, so scans are not re-projected into local event time for you. If your report needs "9am on the second day of the fair", apply the event's zone yourself — you know which city it was in.

Nulls

Nullability is stated per column in $metadata, and null is common and meaningful:

  • Person and address fields are null where the visitor did not supply them.
  • CurrencyShort can be null on rows with no monetary value.
  • Legitimation, promotion-code, upselling and cross-selling families are null on tickets they do not apply to.
  • Several status columns are nullable, and null means "not applicable here" rather than a state.
  • A null boolean is neither true nor false — $filter=SomeFlag eq false will not match it. Filter eq null explicitly when you mean it.

Getting the full list

GET /odata/v1/$metadata returns every column with its type, nullability, key membership and business label. See Field reference.