Booking Schema

The booking is one of the four primary Versa event types. It shares the same underlying structure as a receipt, but with fewer required fields — payment has typically not yet occurred at the time of booking, so totals and payment details may be partial or absent.

A JSON Schema document and corresponding TypeScript Types are available on GitHub or via the @versa/schema package.

NOTE

A booking is most commonly used for travel reservations — car_rental, flight, lodging, and transit_route itemizations — but the schema accepts any itemization template.

Differences from the Receipt Schema

Bookings relax a number of fields that are required on a receipt:

  • Header: Only currency and total are required. subtotal, paid, and invoiced_at are all optional on a booking (they become required once the transaction settles as a receipt). A booked_at timestamp is available for the time at which the booking was made.
  • Payments: The payments array may be omitted or set to null. header.paid is typically 0 until payment occurs.
  • Footer: The footer may be omitted or set to null.
  • Lodging itemization: items is optional — the itemization breakdown is often not known at the time of booking.

All other objects and primitives are shared with the receipt schema; the sections below document a booking in full for convenience.

Sections

Booking objects are composed of four sections:

  1. Header: Top-level fields, e.g. merchant details, totals, booking date.
  2. Itemization: Description, quantity, unit cost, and total for each line item. Type-specific templates describe different purchase types, e.g. flight, lodging, car rental.
  3. Footer: Optional merchant-defined actions and supplemental text. For example: 'Cancel Booking,' 'Manage Reservation,' 'Contact Support.'
  4. Payments: Optional payment status and details.

Wrapper

Booking objects are wrapped in a top-level envelope that includes the schema version:

{
  "schema_version": "2.3.0",
  "header": { ... },
  "itemization": { ... },
  "payments": null,
  "footer": null
}
FieldTypeDescription
schema_versionstringVersion of the schema; useful for validating the object.
headerobjectHeader.
itemizationobjectItemization object.
paymentsnullable arrayList of payments. May be null or omitted if payment has not yet occurred.
footernullable objectThe footer includes actions and supplemental text. May be null.

The header provides a high-level view of the booking, describing the "who," "when," and "where" (the "what" is covered in the itemization section). On a booking, only currency and total are required; totals not yet known can be left null. An example header:

"header": {
  "currency": "usd",
  "total": 6332,
  "subtotal": null,
  "paid": 0,
  "booked_at": 1713295619,
  "invoiced_at": null,
  "invoice_number": "BK-1024",
  "lifecycle_status": "active",
  "customer": null,
  "location": null
}
FieldTypeDescription
currencystringA lowercase ISO 4217 currency code, e.g. usd. Required.
totalintegerTotal amount. In the currency specified and in the smallest currency unit. Required.
subtotalnullable integerSubtotal (before taxes, fees, tip). Optional on a booking.
paidnullable integerSum of all payments. Typically 0 on a booking, or null if unknown.
booked_atnullable integerTime at which the booking was created. Measured in seconds since the Unix epoch.
invoiced_atnullable integerTime at which the invoice was created. Optional on a booking — typically unset until the booking settles.
invoice_numbernullable stringUnique identifier for the booking / confirmation.
mccnullable stringMerchant Category Code. This value should match the value on the card network.
third_partynullable objectThird party involved in the transaction, where applicable.
customernullable objectCustomer involved in the transaction, where applicable.
locationnullable objectPlace object for the merchant. Also where you can set the primary timezone.
invoice_asset_idnullable stringAsset id of uploaded invoice PDF or image.
receipt_asset_idnullable stringAsset id of uploaded receipt PDF or image.
tripnullable objectOptional trip grouping — for associating the booking with a broader trip.
lifecycle_statusnullable enumOne of active, canceled, refunded. Used to communicate the current state of the booking.
Trip Object

Trip

Optional grouping used to associate a booking with a broader trip (e.g. a multi-leg itinerary composed of flight, lodging, and car rental bookings).

FieldTypeDescription
idnullable stringStable identifier for the trip.
namenullable stringHuman-readable trip name.
descriptionnullable stringOptional longer trip description.

Itemization

The Itemization section describes the goods and services that compose the booking. Based on the type of booking, the object conforms to one of eight templates: General, Car Rental, E-commerce, Flight, Lodging, Service, Subscription, or Transit Route. Exactly one itemization template should be non-null. When in doubt for a travel booking, use flight, lodging, car_rental, or transit_route.

"itemization": {
  "general": null,
  "car_rental": null,
  "ecommerce": null,
  "flight": { ... },
  "lodging": null,
  "service": null,
  "subscription": null,
  "transit_route": null
}
General Object

General

FieldTypeDescription
itemsarrayAn array of generic item objects.
invoice_level_adjustmentsarrayArray of adjustments applied at the top (invoice) level. These are independent of line item adjustments, which are added at the line item level.
Car Rental Object

Car Rental

"car_rental": {
  "rental_at": 1713196492,
  "return_at": 1713415500,
  "confirmation_number": null,
  "record_locator": null,
  "vendor_code": null,
  "rental_location": { ... },
  "return_location": { ... },
  "vehicle": {
    "description": "Polestar 2",
    "image": null,
    "license_plate_number": null,
    "vehicle_class": "EDAE"
  },
  "drivers": [{ ... }],
  "odometer_reading_in": null,
  "odometer_reading_out": null,
  "items": [ ... ],
  "metadata": [],
  "invoice_level_adjustments": []
}
FieldTypeDescription
rental_atintegerRental time. Measured in seconds since the Unix epoch.
return_atintegerReturn time. Measured in seconds since the Unix epoch.
confirmation_numbernullable stringRental confirmation number.
record_locatornullable stringPNR or booking record locator.
vendor_codenullable stringTwo-letter GDS vendor code, e.g. ZI for Avis, ZB for Budget.
rental_locationobjectA place describing the rental location.
return_locationobjectA place describing the return location.
vehiclenullable objectA vehicle object.
driversnullable arrayArray of person objects.
odometer_reading_innullable integer
odometer_reading_outnullable integer
itemsarrayAn array of generic item objects — typically the base rental rate plus any prepaid add-ons known at booking.
metadataarrayArray of metadata objects, for any additional info.
invoice_level_adjustmentsarrayArray of adjustments applied at the top (invoice) level. These are independent of line item adjustments, which are added at the line item level.

Vehicle

FieldTypeDescription
descriptionstringType of car.
imagenullable stringImage of car.
license_plate_numbernullable string
vehicle_classnullable stringACRISS car code, four letters.
E-commerce Object

E-commerce

For online orders, with shipping info. If items have not been assigned to a shipment, add those items to invoice_level_line_items. Once they've been assigned to a shipment, move them to shipment.items.

FieldTypeDescription
invoice_level_line_itemsarrayAn array of item objects at the invoice level. For items that are part of shipment, move them under the shipment object.
shipmentsarrayAn array of shipment objects.
invoice_level_adjustmentsarrayArray of adjustments applied at the top (invoice) level. These are independent of line item adjustments, which are added at the line item level.

Shipment

FieldTypeDescription
itemsarrayAn array of item objects at shipment level.
carriernullable stringShipping carrier name (e.g., "FedEx", "UPS").
tracking_numbernullable stringLabel that appears on the button.
expected_delivery_atnullable intMeasured in seconds since the Unix epoch.
shipment_statusnullable enumOne of prep, in_transit, delivered.
destination_addressnullable objectAn address object.
Flight Object

Flight

FieldTypeDescription
ticketsarrayAn array of ticket objects.
itinerary_locatornullable string
invoice_level_adjustmentsarrayArray of adjustments applied at the top (invoice) level. These are independent of line item adjustments, which are added at the line item level.

Tickets

FieldTypeDescription
segmentsarrayArray of segments.
numbernullable string
record_locatornullable stringPNR.
passengernullable objectA person object.
farenullable integerOptional, only needed if fares are not included on the contained segments.
taxesarrayOptional, only needed if taxes are not included on the contained segments.

Segments

FieldTypeDescription
departure_airport_codestringThe three-letter IATA airport code that the flight departed from.
arrival_airport_codestringThe three-letter IATA airport code of the flight's destination.
farenullable integerShould be included, unless fare is on the parent ticket object instead.
taxesarrayArray of tax objects.
departure_atnullable integerDeparture time. Measured in seconds since the Unix epoch.
arrival_atnullable integerArrival time. Measured in seconds since the Unix epoch.
departure_tznullable stringA list of possible time zone values is maintained at the IANA Time Zone Database.
arrival_tznullable stringA list of possible time zone values is maintained at the IANA Time Zone Database.
flight_numbernullable stringThe two-letter IATA airline designator followed by a one to four digit number (e.g. 'DL123').
class_of_servicenullable string
seatnullable string
aircraft_typenullable stringThe ICAO code of the aircraft.
metadataarrayArray of metadata objects, for any additional info.
adjustmentsarrayArray of adjustment objects.
Lodging Object

Lodging

On a booking, the folio is typically not yet known, so items is optional — you can send just the room rate (if known) or omit items entirely.

"lodging": {
  "check_in": 1713196492,
  "check_out": 1713473361,
  "confirmation_number": "ABC123",
  "chain_code": "MC",
  "property_id": null,
  "record_locator": null,
  "guests": [{
    "first_name": "Susan",
    "last_name": "Doe",
    "email": "sdoe@platform.co",
    "phone": "+14155552671",
    "metadata": []
  }],
  "room": null,
  "location": { ... },
  "items": null,
  "metadata": [],
  "invoice_level_adjustments": []
}
FieldTypeDescription
check_inintCheck-in date-time. Measured in seconds since the Unix epoch. Required.
check_outintCheck-out date-time. Measured in seconds since the Unix epoch. Required.
locationobjectA place object describing the hotel / lodging. Required.
confirmation_numbernullable stringHotel confirmation number.
chain_codenullable stringTwo-character chain code, e.g. MC for Marriott, HY for Hyatt.
property_idnullable stringProperty identifier. Examples: gds.sabre:19835, gds.amadeus:BWNYCMQ, chain.marriott:NYCMQ, giata:17324.
record_locatornullable stringPNR or booking record locator.
guestsnullable arrayArray of person objects.
roomnullable stringRoom number.
itemsnullable arrayAn array of generic item objects. Optional on a booking — typically the full folio is not known until check-out.
metadataarrayArray of metadata objects, for any additional info.
invoice_level_adjustmentsarrayArray of adjustments applied at the top (invoice) level. These are independent of line item adjustments, which are added at the line item level.
Service Object

Service

For airport parking, SaaS subscriptions, phone bills, etc.

FieldTypeDescription
service_itemsarrayAn array of service item objects.
invoice_level_adjustmentsarrayArray of adjustments applied at the top (invoice) level. These are independent of line item adjustments, which are added at the line item level.

Service Item

FieldTypeDescription
amountintegerSubtotal for the line item (typically quantity × unit_cost + adjustments). Does not include taxes.
service_locationnullable objectA place object describing the location where the service was provided (e.g., parking lot, service center).
recurringbooleanWhether this is a recurring service.
descriptionstringDescription of the service.
intervalnullable enumOne of day, week, month or year.
interval_countnullable integerThe number of intervals (specified in the interval attribute) between subscription billings. For example, interval=month and interval_count=3 bills every 3 months.
current_period_start_atnullable integerStart of the current period of the service. Measured in seconds since the Unix epoch.
current_period_end_atnullable integerEnd of the current period. Measured in seconds since the Unix epoch.
quantitynullable numberQuantity of items.
unit_costnullable integerCost of the service in the smallest currency unit.
taxesarrayArray of tax objects.
metadataarrayArray of key/value metadata pairs, e.g. SKU.
adjustmentsarrayArray of adjustment objects.
Subscription Object

Subscription

For pre-paid or recurring subscription purchases.

FieldTypeDescription
subscription_itemsarrayAn array of subscription item objects.
invoice_level_adjustmentsarrayArray of adjustments applied at the top (invoice) level. These are independent of line item adjustments, which are added at the line item level.

Subscription Item

FieldTypeDescription
amountintegerSubtotal for the line item (typically quantity × unit_cost + adjustments). Does not include taxes.
subscription_typeenumOne of one_time or recurring.
descriptionstringDescription of the subscription.
intervalnullable enumOne of day, week, month or year.
interval_countnullable integerThe number of intervals between billings.
current_period_start_atnullable integerStart of the current period. Measured in seconds since the Unix epoch.
current_period_end_atnullable integerEnd of the current period. Measured in seconds since the Unix epoch.
quantitynullable numberQuantity of items.
unit_costnullable integerCost in the smallest currency unit.
taxesarrayArray of tax objects.
metadataarrayArray of key/value metadata pairs.
adjustmentsarrayArray of adjustment objects.
Transit Route Object

Transit Route

A route, typically used by rideshare / taxi services, or rail / bus / ferry / etc.

FieldTypeDescription
transit_route_itemsarrayArray of transit route item objects.
invoice_level_adjustmentsarrayArray of adjustments applied at the top (invoice) level. These are independent of line item adjustments, which are added at the line item level.

Transit Route Item

FieldTypeDescription
departure_locationnullable objectThe origin place object.
arrival_locationnullable objectThe destination place object.
fareintegerFare for this leg. Required.
departure_atnullable integerDeparture time. Measured in seconds since the Unix epoch.
arrival_atnullable integerArrival time. Measured in seconds since the Unix epoch.
modenullable enumOne of car, taxi, rail, bus, ferry, other.
passengernullable objectA person object.
polylinenullable stringAn encoded polyline of the route.
taxesarrayArray of tax objects.
metadataarrayArray of key/value metadata pairs.
adjustmentsarrayArray of adjustment objects.

The footer on a booking is optional (it may be set to null or omitted).

FieldTypeDescription
actionsnullable arrayList of actions.
supplemental_textnullable stringTerms and conditions or other info. Supports Markdown

Actions

Merchants have the option to provide useful next actions in the Actions section. On a booking, common actions include 'Manage Reservation,' 'Cancel Booking,' or 'Contact Support.' There is a limit of three actions.

NOTE

For security reasons, we recommend that the action urls share the same domain as the sending merchant, wherever possible. Authoritative social media sites like Instagram and Facebook are also common. Action URLs that don't share a domain with the sending merchant, and aren't to an authoritative site, may be filtered by the receiver.

"actions": [
  {
    "name": "Manage Reservation",
    "url": "https://yourco.com/reservations/be1e1b57-8fe9-4729-8b7d-f9a4690bb2cd"
  },
  {
    "name": "Cancel Booking",
    "url": "https://yourco.com/cancel/ad058b82-d0dd-4534-a915-d448df098167"
  }
]
FieldTypeDescription
namestringLabel that appears on the button.
urlstringAction deep link.

Payments

Payments are optional on a booking — the payments field may be null or omitted entirely when the transaction has not yet been paid. When a payment (e.g. a deposit or a pre-pay) has been collected, record it here as you would on a receipt.

"payments": [
  {
    "paid_at": 1679609767,
    "payment_type": "card",
    "amount": 234,
    "card_payment": {
      "last_four": "7806",
      "network": "mastercard"
    },
    "ach_payment": null
  }
]
FieldTypeDescription
amountint
paid_atintMeasured in seconds since the Unix epoch.
payment_typenullable enumOne of card or ach.
card_paymentnullable objectCard payment object.
ach_paymentnullable objectACH payment object.
Card Payment Object

Card Payment

FieldTypeDescription
last_fourstringThe last four digits of the card number.
networknullable enumOne of amex, diners, discover, eftpos_au, jcb, mastercard, unionpay, or visa.
ACH Payment Object

ACH Payment

FieldTypeDescription
routing_numberstringACH routing number.

Primitives

Foundational objects used throughout the schema. These are identical to the corresponding primitives on the Receipt Schema.

Org Primitive

Org

A merchant, third party, or employer profile.

FieldTypeDescription
namestringThe organization's common name.
legal_namenullable stringThe organization's legal name.
brand_colornullable stringHex color.
logonullable stringDeprecated: Logo image url, in a square aspect ratio. Use logo_asset_id instead.
logo_asset_idnullable stringAsset id of uploaded logo image. Recommended size 400x400 in a square aspect ratio.
websitenullable stringOrganization's primary website url.
vat_numbernullable string
addressnullable objectAn address object.
Person Primitive

Person

FieldTypeDescription
first_namenullable stringLegal first name.
last_namenullable stringLegal last name.
preferred_first_namenullable string
emailnullable string
phonenullable stringPhone number in the E.164 format.
metadataarrayArray of metadata objects, for any additional info.
Place Primitive

Place

Describes a brick-and-mortar location.

FieldTypeDescription
namenullable stringPlace name.
addressnullable objectAn address object.
phonenullable stringPhone number in the E.164 format.
urlnullable stringURL for specific place, e.g. chain.com/store-id.
google_place_idnullable stringMapping to the Google Places database.
imagenullable stringImage representing the place.
Address Primitive

Address

FieldTypeDescription
street_addressnullable string
citynullable string
regionnullable stringTwo letter region code.
countrynullable stringTwo letter ISO 3166 country code.
postal_codenullable string
latnullable number
lonnullable number
tznullable stringA list of possible time zone values is maintained at the IANA Time Zone Database.
Item Primitive

Item

A generic line item.

FieldTypeDescription
descriptionstringDescription of the good / service.
amountintegerSubtotal for the line item (typically quantity × unit_cost + adjustments). Does not include taxes or adjustments.
quantitynullable numberQuantity of items.
unit_costnullable integerCost of the good / service in the smallest currency unit.
unitnullable stringField describing the unit type, typically for weight or volume -based values, e.g. 'kg' or 'gallons'. Leave null for 'each'.
product_image_asset_idnullable stringAsset id of uploaded product image.
groupnullable stringGrouping of line items.
unspscnullable stringThe 8-digit UNSPSC code for this item.
urlnullable stringURL to product page.
datenullable stringDate corresponding to the line item, in ISO 8601 format (YYYY-MM-DD), e.g. for nightly rate in a hotel folio.
taxesarrayArray of tax objects.
metadataarrayArray of key/value metadata pairs, e.g. SKU.
adjustmentsarrayArray of adjustment objects.
Metadata Primitive

Metadata

Use line item metadata to track things not otherwise in the schema. E.g. SKU, Size, Color, UNSPSC Code, etc.

FieldTypeDescription
keystringThe type of metadata, e.g. 'Size', 'Brand', 'Product Condition', 'Special Instructions', etc.
valuestringThe corresponding value.
Tax Primitive

Tax

FieldTypeDescription
amountintThe total tax, in the smallest currency unit.
namestringE.g. 'VAT' or 'GST'.
ratenullable numberThe tax rate, e.g. 0.05 for 5%.
Adjustment Primitive

Adjustment

To be used for discounts, tip, fees, surcharges, tolls.

FieldTypeDescription
amountintThe total of the adjustment, in the smallest currency unit. Positive value for tip / fee, negative value for discount.
adjustment_typeenumOne of discount, tip, fee, add_on, other.
namenullable stringThe name of the adjustment.
ratenullable numberThe adjustment rate, e.g. -0.1 for 10% discount, or 0.2 for 20% tip. Null for fixed adjustment.

Definitions & Formatting

Currency Values

All API requests expect amounts to be provided in a currency's smallest unit. For example, to represent 10 USD, provide an amount value of 1000 (that is, 1000 cents). For zero-decimal currencies, still provide amounts as an integer but without multiplying by 100. For example, to represent ¥500, provide an amount value of 500.

Images

Images must be hosted at public URLs. The images are likely to be indexed by the receiver. For best results, no image dimension should be less than 400px, or greater than 2,000px.

Cancelations

To mark a booking as canceled, send an update event with header.lifecycle_status set to canceled. You may also send a terminal update with an empty itemization as with a receipt — see the Receipt Cancelations section for details.

{
  "schema_version": "2.3.0",
  "header": {
    "currency": "usd",
    "total": 0,
    "paid": 0,
    "booked_at": 1713295619,
    "lifecycle_status": "canceled"
  },
  "itemization": {},
  "footer": null,
  "payments": null
}