The Versa schema is the core data model for structured transaction records in the Versa protocol. Schema objects include "header" information — the merchant name, merchant logo, total amount, transaction date, etc. — as well as "line item" details — the quantity, description, and cost of each item purchased.
A JSON Schema document and corresponding TypeScript Types are available on GitHub or via the @versa/schema package.
All primary event types share the same underlying schema structure, but differ in which fields are expected to be present. The event_type is typically inferred from the data provided, but can be specified in the event registration payload.
receipt: A completed transaction. Includes payments.
booking: A travel reservation. Payments are not required, and header.paid is typically zero. Bookings are only valid for travel itemization types: car_rental, flight, lodging, or transit_route.
invoice: An outstanding bill. Structurally identical to a receipt, but header.paid is less than header.total, indicating payment is still due.
itinerary: Travel information without financial data. Excludes totals, taxes, and payments. Focused on travel details only. See the Itinerary Schema for details.
Header: Top-level fields, e.g. merchant details, totals, transaction date.
Itemization: Description, quantity, unit cost, and total for each line item. Type-specific templates describe different purchase types, e.g. flight, e-commerce purchase, service.
Footer: Optional merchant-defined actions, pivoting off the purchase, and supplemental text. For example: 'Contact Support,' 'Buy Again,' 'Manage Subscription.'
Payments: Payment status and details. Required for receipt and invoice event types; omitted for itinerary; optional for booking.
The header provides a high-level view of the transaction, describing the "who," "when," and "where" (the "what" is covered in the itemization section). An example header:
Use the optional third party object in cases where the sender is a platform / broker. For example, if a coffee shop uses Square to process sales, the 'sending merchant' would be Square and the 'third party merchant' would be the coffee shop. The make_primary flag specifies whether the sending merchant or the third party merchant should get top billing on the receipt.
Field
Type
Description
relation
enum
One of bnpl, delivery_service, marketplace, payment_processor, platform, point_of_sale.
make_primary
boolean
Determines whether the merchant or third party gets top billing on the receipt.
The Itemization section describes the goods and services that compose the purchase. Based on the type of purchase, the object conforms to one of seven templates: General, Car Rental, E-commerce, Flight, Lodging, Service, or Transit Route. Exactly one itemization template must be non-null. When in doubt, use the 'general' template.
NOTE
For booking event types, only the travel itemization types are valid: car_rental, flight, lodging, or transit_route. For itinerary event types, general and ecommerce are also excluded. See the Itinerary Schema for the full itinerary itemization spec.
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. View a complete E-commerce receipt example.
Field
Type
Description
invoice_level_line_items
array
An array of item objects at the invoice level. For items that are part of shipment, move them under the shipment object.
Subtotal for the line item (typically quantity × unit_cost + adjustments). Does not include taxes.
service_location
nullable object
A place object describing the location where the service was provided (e.g., parking lot, service center).
recurring
boolean
Whether this is a recurring service.
description
string
Description of the service.
interval
nullable enum
One of day, week, month or year.
interval_count
nullable integer
The 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_at
nullable integer
Start of the current period of the service. Measured in seconds since the Unix epoch.
current_period_end_at
nullable integer
End of the current period. Measured in seconds since the Unix epoch.
Merchants have the option to provide useful next actions in the Actions section. An action is typically a deep link to a page within the merchant's website. For example 'Buy Again' might deep link to a pre-filled shopping cart. 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.
The org object is used to describe both a sending merchant and a third party merchant. In the former case, the org object is expanded implicitly via the Versa Registry, whereas in the latter case, the org object is explicitly encoded into the receipt, via the header third_party object.
{"street_address":"123 Main St","city":"Anytown","region":"CA","country":"US","postal_code":"12345","lat":37.7749,"lon":-122.4194,"tz":"America/Los_Angeles"}
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 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.