Proto bundle

// Feeds declaration
edition = "2023";

package ext.travel.ttd.proto.feeds.v1;

message EventFeed {
  // List of the events.
  repeated Event data = 1;
}

// Represents a single event.
message Event {
  // Unique across the feed.
  // Max length: 255. Allowed characters are alphanumeric, _, and -.
  // Required.
  string id = 1
      ;

  // The title of the event in plain text.
  // Recommended to not exceed length of 50 in any language.
  // Max length: 150.
  // Required.
  LocalizedTextSet title = 2
      ;

  // The description of the event. Limited formatting options are allowed in the
  // HTML format. Supported tags:
  //   * h1-h5
  //   * ul, ol, li
  //   * strong, italic, em
  //   * p, br
  // Other tags are not supported and will be removed. CSS, tables, style
  // property, `a` links are not supported. Images are not allowed, use the
  // related_media field instead.
  // Recommended to not exceed length of 10000 in any language.
  // Max length: 16000.
  // Recommended.
  LocalizedTextSet description = 3
      ;

  // Detailed timing information for the event.
  // Required.
  TimeInfo time_info = 4
      ;

  // The physical location where the event is held.
  // Required.
  Location venue = 5
      ;

  // List of the performing or related entities in the Event. These are meant to
  // reflect the artist/team/group/etc that a person might see on the ticket or
  // broader concepts (e.g. concert tours, festivals).
  // Max number of entities: 100.
  // Strongly recommended.
  repeated Entity related_entities = 6
      ;


  enum EventType {
    // Not specified. Do not use.
    EVENT_TYPE_UNSPECIFIED = 0;
    EVENT_TYPE_CONCERT = 1;
    EVENT_TYPE_SPORTS = 2;
    EVENT_TYPE_THEATER = 3;
    EVENT_TYPE_WORKSHOP = 4;
    EVENT_TYPE_CONVENTION = 5;
    EVENT_TYPE_TOUR = 6;
    EVENT_TYPE_SHOW = 7;
    EVENT_TYPE_FAIR = 8;
    EVENT_TYPE_FESTIVAL = 9;
    EVENT_TYPE_EXPO = 10;
  }

  // A list of event types that best describe the event.
  // Max number of types: 5.
  // Optional.
  repeated EventType event_types = 14
      ;

  // Tickets available for this event.
  // Max number of tickets: 20.
  // Required.
  repeated Ticket tickets = 8
      ;

  // Related media such as photos or videos.
  // Max number of media: 30.
  // Recommended.
  repeated Media related_media = 9
      ;

  // Provider brand name. This should be the brand that is owned by the partner.
  // If partner is acting as an aggregator and the brand is not owned by them,
  // they should instead set the ticket's `seller_info` field.
  // Max length: 50.
  // Optional.
  LocalizedTextSet brand_name = 10
      ;

  // Landing page URL for this event. The page should include a button to start
  // the booking/checkout flow.
  // Do not use link.mobile_url or link.localized_mobile_url.
  // Required.
  DeepLink event_url = 11
      ;

  enum PartnerRole {
    PARTNER_ROLE_UNSPECIFIED = 0;
    PARTNER_ROLE_OFFICIAL_SELLER = 1;
    PARTNER_ROLE_AGGREGATOR = 2;
  }

  // Indicates the role of the partner listing the event tickets.
  // Optional.
  PartnerRole partner_role = 12;

  // Information about the creator of the event. Only relevant for platforms
  // that include user-generated content events.
  message EventCreator {
    // Name of the event creator.
    // Max length: 100.
    // Required.
    string name = 1
        ;
  }

  // Information about the creator of the event. Should be used only for
  // partners that include user-generated content events.
  // Optional
  EventCreator event_creator = 13;
}

// Reference to one of the performing entities in the Event. These are meant to
// reflect the artist/team/group/etc that a person might see on the ticket or
// broader concepts (e.g. concert tours, festivals).
message Entity {
  // Unique identifier of the entity in the partner's database.
  // Max length: 255. Allowed characters are alphanumeric, _, and -.
  // Recommended.
  string id = 1
      ;

  // The name of the entity in plain text.
  // Recommended to not exceed length of 50.
  // Max length: 150.
  // Required.
  google.type.LocalizedText name = 2
      ;

  // The official website URL of the entity.
  // Max length: 2000.
  // Recommended.
  string official_website_url = 3
      ;

  // Url of the webpage that unambiguously describes the entity.
  // This is the webpage on the partner's website for the entity if any; for
  // other public URLs of the entity, use related_urls.
  // Max length: 2000.
  // Recommended.
  string url = 4
      ;

  // Other urls that might identify the entity.
  // Max length: 2000. Max number of links: 10.
  // Optional.
  repeated string related_urls = 5
      ;

  // ID as used by MusicBrainz.
  // Fixed length: 36. Allowed characters are hexadecimal (0-9, a-f) and -.
  // Optional.
  string musicbrainz_id = 6
      ;

  // The YouTube channel id.
  // If provided may be used as an additional input for entity matching.
  // Channel ids start with characters `UC` followed by a variable number of
  // additional characters. Allowed characters are hexadecimal (0-9, a-f) and -.
  // Optional.
  string youtube_channel_id = 9
      ;

  // The type of the entity.
  enum EntityType {
    // Not specified. Do not use.
    ENTITY_TYPE_UNSPECIFIED = 0;

    // The entity represents the music artist or a band performing at a
    // concert or a show.
    ENTITY_TYPE_PERFORMER_MUSICIAN = 1;
    // The entity represents the comedian artist or group of comedians.
    ENTITY_TYPE_PERFORMER_COMEDIAN = 2;
    // The entity represents the magician artist or group of magicians.
    ENTITY_TYPE_PERFORMER_MAGICIAN = 3;
    // The entity represents the online personality (e.g. youtuber, instagramer,
    // podcaster).
    ENTITY_TYPE_PERFORMER_ONLINE_PERSONALITY = 4;
    // The entity represents a sports player.
    ENTITY_TYPE_PERFORMER_SPORTS_PLAYER = 5;
    // The entity represents a sports team.
    ENTITY_TYPE_PERFORMER_SPORTS_TEAM = 6;

    // The entity represent a show. It can refer to a series of events (e.g.
    // 'The Lion King' at West End) or a larger event where the event belongs to
    // (e.g. 'Coachella').
    ENTITY_TYPE_SHOW = 7;
    // The entity represents a concert tour (e.g. 'The Mathematics Tour' of Ed
    // Sheeran).
    ENTITY_TYPE_CONCERT_TOUR = 8;
    // The entity represents a sports event that this event is part of (e.g.
    // 'Olympics 2024' or 'FIFA World Cup')
    ENTITY_TYPE_SPORTS_TOURNAMENT = 9;
  }

  // The type of the entity.
  // Optional.
  EntityType entity_type = 8
      ;

  // The role of the performer in the event.
  enum PerformerRole {
    // Not specified. Do not use.
    PERFORMER_ROLE_UNSPECIFIED = 0;
    // The performer represents a headliner or leading performer at the event.
    PERFORMER_ROLE_HEADLINER = 1;
    // The performer represents a supporting performer at the event.
    PERFORMER_ROLE_SUPPORTER = 2;
    // The performer represents the home team at the (sports) event. Only
    // applicable when PerformerType is PERFORMER_TYPE_SPORTS_TEAM.
    PERFORMER_ROLE_HOME_TEAM = 3;
    // The performer represents the home team at the (sports) event. Only
    // applicable when PerformerType is PERFORMER_TYPE_SPORTS_TEAM.
    PERFORMER_ROLE_AWAY_TEAM = 4;
  }

  // The role of the performer in the event. Should be used only when the entity
  // refers to a person or a group of people (i.e. entity type starts with
  // "ENTITY_TYPE_PERFORMER_*").
  // Optional.
  PerformerRole performer_role = 7
      ;
}

// Ticket available for the Event.
message Ticket {
  // Ticket ID. Must be unique within the event.
  // Max length: 255. Allowed characters are alphanumeric, _, and -.
  // Required.
  string id = 1
      ;

  // The title of the ticket in plain text, e.g. "Category 1 ticket".
  //
  // If there is only a single ticket, the ticket title may be the same as the
  // event title. If multiple tickets are present, the title must be
  // unique to the ticket.
  // Recommended to not exceed length of 50 in any language.
  // Max length: 150.
  // Recommended.
  LocalizedTextSet title = 2
      ;

  // The description of the ticket. Limited formatting options are allowed in
  // the HTML format, see event description field for more details.
  // Recommended to not exceed length of 10000 in any language.
  // Max length: 16000.
  // Recommended.
  LocalizedTextSet description = 3
      ;

  // Additional information about the seller of this ticket. In certain cases
  // the seller may differ from the provider of the event (e.g. in cases of
  // aggregators providing tickets for sellers they have aggregated).
  // Optional.
  SellerInfo seller_info = 9;

  // URL for this ticket. The page should include a button to start the
  // booking/checkout flow.
  // Required.
  repeated ReferralLink referral_urls = 4
      ;

  // Lowest base adult general-accessible ticket price.
  // Recommended.
  Price price = 5;

  // Information about the availability of the ticket.
  // Recommended.
  AvailabilityInfo availability_info = 6;

  // Cancellation policy for this ticket.
  // Optional.
  CancellationPolicy cancellation_policy = 7;

  // Predetermined inventory type of a single ticket of this type.
  enum InventoryType {
    // The inventory type is unspecified.
    INVENTORY_TYPE_UNSPECIFIED = 0;
    // Primary inventory.
    INVENTORY_TYPE_PRIMARY = 1;
    // Verified resale inventory.
    INVENTORY_TYPE_VERIFIED_RESALE = 2;
    // Resale inventory.
    INVENTORY_TYPE_RESALE = 3;
    // Aggregator inventory.
    INVENTORY_TYPE_AGGREGATOR = 4;
  }

  // Predetermined inventory type of a single ticket of this type.
  // Optional.
  InventoryType inventory_type = 8;
}

// Additional information about the seller of a ticket.
message SellerInfo {
  // The name of the ticket seller. This may differ from the name of the event
  // provider in certain cases, e.g. aggregators providing tickets for sellers
  // that they have aggregated.
  // Max length: 150.
  // Optional.
  LocalizedTextSet name = 1
      ;

  // The logo URL of the seller. If the logo cannot be inferred from the event
  // url (e.g. because the provided URL redirects to another seller) it may be
  // explicitly specified here.
  // Max length: 2000.
  // Optional.
  string logo_url = 2
      ;
}

// Referral link.
message ReferralLink {
  // Landing page URL. The page should include a button to start the
  // booking/checkout flow.
  // Do not use link.mobile_url or link.localized_mobile_url.
  // Required.
  DeepLink link = 1
      ;

  // Predetermined event surface associated with a action link.
  enum Surface {
    // The surface is unspecified.
    SURFACE_UNSPECIFIED = 0;
    // The action link is booking a event ticket in Search.
    SURFACE_SEARCH = 1;
    // The action link is booking a event ticket in YouTube.
    SURFACE_YOUTUBE = 2;
    // The action link is clicking on an ad for the event.
    SURFACE_ADS = 3;
  }

  // Predetermined event surface associated with a link.
  // Optional.
  Surface surface = 2;
}

// Information about the price.
message Price {
  // Price value, must match the final price on the checkout page. Currency will
  // be converted to the user currency on rendering.
  // Required when is_free is false.
  google.type.Money value = 1
      ;

  // Admission or ticket is free. Must be set to true for zero-price options.
  // Optional, default is false.
  bool is_free = 2;

  // Booking fees included in the final price.
  // Optional.
  google.type.Money per_ticket_fee = 3
      ;

  // Taxes included in the final price.
  // Optional.
  google.type.Money per_ticket_tax = 4
      ;

  // Indicates the price format displayed on the landing page.
  //
  // This field allows Google surfaces to show the same price format as used by
  // the landing page. Consistent price formats improve conversion rate and
  // reduce confusion.
  enum PriceDisplayType {
    // The price display type is unspecified. Google will determine which
    // format to show.
    PRICE_DISPLAY_TYPE_UNSPECIFIED = 0;
    // The price shown on the landing page is the base price.
    PRICE_DISPLAY_TYPE_BASE = 1;
    // The price shown on the landing page includes all fees and taxes.
    PRICE_DISPLAY_TYPE_ALL_IN = 2;
  }

  // Predetermined display type of a single option price.
  PriceDisplayType price_display_type = 5;
}

// Values of the localized fields.
message LocalizedTextSet {
  // Per-locale LocalizedText values.
  // Maximum repeatedness: 50
  // At least one value is required
  repeated google.type.LocalizedText localized_texts = 1
      ;
}

// Time information about a time slot for a service or event.
message TimeInfo {
  // Event start time - seconds since epoch UTC.
  // Required
  int64 start_seconds =
      1
      ;

  // Set to true if the start sec has not been decided.
  // The start_sec in this case must be set to the earliest potential time.
  bool start_to_be_decided = 2;

  // Event end time - seconds since epoch UTC.
  // If provided must be not earlier than start_seconds.
  // Optional.
  int64 end_seconds =
      3
      ;

  // Door opening time -in seconds since the epoch UTC.
  // If provided must be not later than start_seconds.
  // Optional.
  int64 door_open_seconds =
      4
      ;
}

message Media {
  // URL of this media source. Google will crawl the media hosted at this URL.
  // Max length: 2000.
  // Required.
  string url = 1
      ;

  enum MediaType {
    // Don't use, for backwards compatibility only.
    MEDIA_TYPE_UNSPECIFIED = 0;
    // Indicates the media provided by the url is a photo.
    MEDIA_TYPE_PHOTO = 1;
  }
  // Type of this media source.
  // Required.
  MediaType type = 2
      ;

  // Attribution information about the source of the media. Note that if
  // the attribution is required to display with the media to give credit to
  // photographer or agency, this field must be set.
  // Recommended to not exceed length of 1000 in any language.
  // Max length: 2000.
  // Optional.
  LocalizedTextSet attribution = 3
      ;
}

// Deep link definition. Can include value parameters that will be expanded on
// serve time.
message DeepLink {
  // Landing page URL template for desktop. If both `url` and `localized_url`
  // are provided, the former is used as a fallback in case
  // no URL matches the user’s locale.
  // Max length: 2000.
  // Either `url` or `localized_url` is required.
  string url = 1
      ;


  // Localized landing page URL template for desktop. If both `url` and
  // `localized_url` are provided, the former is used as a fallback in case
  // no URL matches the user’s locale.
  // Max length: 2000.
  // Max number of locales: 50.
  // Either `url` or `localized_url` is required.
  LocalizedTextSet localized_url = 3
      ;

}

// Availability information of a time slot or ticket for a service or event.
message AvailabilityInfo {
  // On sale start time - seconds since epoch UTC
  // Optional.
  int64 onsale_start_seconds = 1 [(googlesql.format) = TIMESTAMP_SECONDS];

  // On sale end time - seconds since epoch UTC
  // Optional.
  int64 onsale_end_seconds = 2 [(googlesql.format) = TIMESTAMP_SECONDS];

  // The total number of tickets (or spots) that were originally available for
  // this availability.
  // Optional.
  int32 spots_total = 3;

  // The current number of tickets (or spots) still available for purchase for
  // this availability.
  // Required.
  int32 spots_available = 4
      ;
}

// Cancellation policy for a product.
message CancellationPolicy {
  // Defines a single refund condition. Multiple refund conditions could be
  // used together to describe "refund steps" as various durations before the
  // service start time.
  message RefundCondition {
    // Duration in seconds before the start time, until when the customer can
    // receive a refund for part of the service's cost specified in
    // `refund_percent`.
    // When unset or set to 0 the service can be cancelled at any time.
    // Optional.
    uint32 min_duration_before_start_time_sec = 1
        ;

    // The percent that can be refunded, as long as the service booking is
    // cancelled at least `min_duration_before_start_time` before the service
    // start time, in the range of [0, 100].
    // When unset or set to 0, the service is not refundable. When set to 100
    // this service is fully refundable.
    // Optional.
    uint32 refund_percent = 2
        ;

    // A flat fee deducted on refund. Could be used separately, or in
    // combination with the refund_percent above. In the latter case, refund
    // percent applies first, then the fee is deducted.
    // Optional.
    google.type.Money refund_fee = 3
        ;
  }
  // Zero or more refund conditions applicable to the policy.
  // Max number of refund conditions: 10.
  repeated RefundCondition refund_conditions = 1
      ;
}

message Location {
  // At least one of (location, description) must be set, and we highly
  // recommend populating location wherever possible.
  //
  // To emphasize, both fields can be populated together, e.g. you can set
  // Central Park New York for the location and "In front of the 72 Street
  // Station" for the description.
  GeoLocation location = 1
      ;

  // Additional description in human-readable form, e.g.
  //     "On the left side of the fountain on the Palace square".
  // At least one of (location, description) must be set.
  // Recommended to not exceed length of 1000 in any language. Max length: 2000.
  LocalizedTextSet description = 2
      ;
}

message GeoLocation {
  // Required (exactly one variant from oneof).
  // See
  // https://developers.google.com/travel/things-to-do/guides/partner-integration/location
  // for detailed guidelines.
  oneof value {

    // Place ID as defined by the Places API:
    //   https://developers.google.com/places/web-service/place-id
    //
    // Uniquely identifies a POI on Google.
    // It can be sourced using the Places API endpoints, for instance Place
    // Search or Place Autocomplete, or manually using the Find Location Matches
    // tool in Things to Do Center.
    // Max length: 64.
    string place_id = 1
        ;

    // Legacy single-line address.
    // Components are expected to be comma-separated, with the first component
    // being the place name as it is displayed on Google.
    // For higher matching accuracy, use the street address shown on Google for
    // the place.
    //
    // Examples:
    // - "Colosseum, Piazza del Colosseo, 1, 00184 Roma RM, Italy"
    // - "The British Museum, Great Russell St, London WC1B 3DG, United Kingdom"
    // Max length: 200.
    //
    // Deprecated: use `place_info` for higher matching accuracy, which provides
    // a separate field for the place name and supports both structured and
    // unstructured address formats.
    string address = 3 [
      deprecated = true
    ];

    // Structured place information.
    PlaceInfo place_info = 4;

    // Business Profile ID, as found in the Google Business Profile settings
    // page. Use this field when sourcing locations directly from the place
    // owner, who has access to the Google Business Profile for the place and
    // can provide such ID.
    uint64 business_profile_id = 5
        ;

    // Geographic coordinates.
    // This field can only be used to determine a city or geographical region,
    // as it is too ambiguous to identify a specific place or businesses.
    // Use `place_info` instead to match to a specific place by name and
    // coordinates.
    google.type.LatLng lat_lng = 2
        ;
  }
}

message PlaceInfo {
  // Place or business name.
  // For higher matching accuracy, this should be the same as the name shown on
  // Google for the place. For places with a claimed Google Business Profile,
  // this should be the same as the business name configured in the business
  // profile.
  // Max length: 100.
  // Required.
  string name = 1
      ;

  // Phone number, including the international prefix.
  // For higher matching accuracy, this should be the same as the phone number
  // shown on Google for the place.
  // It can include commonly used separator characters.
  // Examples: "+1 212-363-3200", "+91 562 222 7261".
  // Max length: 30.
  // Optional.
  string phone_number = 2
      ;

  // Website URL shown on Google for the place, preferably the URL linked from
  // the business listing in Google Maps or Search for the place.
  // Max length: 1000.
  // Optional.
  string website_url = 3
      ;

  // Geographic coordinates of the place.
  // If left empty, Google will infer the coordinates from the address.
  // Optional, but either `coordinates` or one of `address_type` must be
  // provided.
  google.type.LatLng coordinates = 4
      ;

  // Optional, but either `coordinates` or one of `address_type` must be
  // provided.
  oneof address_type {
    // Structured address.
    // Prefer this format whenever possible for higher matching accuracy.
    StructuredAddress structured_address = 5
        ;

    // Unstructured address.
    // It should not include the place or business name, which must instead be
    // provided separately using the `name` field.
    //
    // Examples:
    // - `name`: "Colosseum", `unstructured_address`: "Piazza del Colosseo, 1,
    // 00184 Roma RM, Italy".
    // - `name`: "The British Museum", `unstructured_address`: "Great Russell
    // St, London WC1B 3DG, United Kingdom".
    //
    // Max length: 400.
    string unstructured_address = 6
        ;
  }
}

message StructuredAddress {
  // Street address, including house number and any other component that cannot
  // be provided using the more specific fields defined below. It should not
  // include the place or business name, which must instead be provided
  // separately using the `name` field under `PlaceInfo`. It should also not
  // include postal code, locality or country as those should be provided using
  // the corresponding fields below.
  //
  // Examples:
  // - "Piazza del Colosseo, 1" for the Colosseum.
  // - "Great Russell St" for The British Museum.
  // - "Champ de Mars, 5 Av. Anatole France" for the Eiffel Tower.
  //
  // Max length: 200.
  // Required.
  string street_address = 1
      ;

  // Locality, generally referring to the city/town portion of an address.
  // Examples: "New York", "Rome", "London", "Tokyo".
  // In regions of the world where localities are not well defined or do not fit
  // into this structure well, leave empty.
  // Max length: 80.
  // Optional.
  string locality = 2
      ;

  // Highest administrative subdivision used for postal addresses of the
  // specific country or region. This can be a state, a region, a province, an
  // oblast, a prefecture, etc.
  // It can be an abbreviation or a full name, depending on how the region is
  // usually represented in the postal addresses of the specific country. For
  // example, "CA" or "California" for US addresses, "RM" for Rome province in
  // Italy.
  // Many countries don't use an administrative area in postal addresses. For
  // instance, this field should not be used for addresses in Switzerland.
  // Max length: 80.
  // Optional.
  string administrative_area = 3
      ;

  // The postal code or zip code.
  // Examples: "75007", "WC1B 3DG", etc.
  // Required if the country supports postal codes, otherwise it should be left
  // empty.
  // Max length: 30.
  // Optional.
  string postal_code = 4
      ;

  // Country code, as defined by Unicode's "CLDR", itself based on the ISO 3166
  // alpha-2 standard. See
  // https://unicode.org/cldr/charts/latest/supplemental/territory_containment_un_m_49.html.
  //
  // Examples: "US" for the United States, "FR" for France, "GB" for the United
  // Kingdom, etc.
  // Max length: 2.
  // Required.
  string country_code = 5
      ;
}

// Represents an amount of money with its currency type.
message google.type.Money {
  // The three-letter currency code defined in ISO 4217.
  string currency_code = 1;

  // The whole units of the amount.
  // For example if `currencyCode` is `"USD"`, then 1 unit is one US dollar.
  int64 units = 2;

  // Number of nano (10^-9) units of the amount.
  // The value must be between -999,999,999 and +999,999,999 inclusive.
  // If `units` is positive, `nanos` must be positive or zero.
  // If `units` is zero, `nanos` can be positive, zero, or negative.
  // If `units` is negative, `nanos` must be negative or zero.
  // For example $-1.75 is represented as `units`=-1 and `nanos`=-750,000,000.
  int32 nanos = 3;
}

// An object that represents a latitude/longitude pair. This is expressed as a
// pair of doubles to represent degrees latitude and degrees longitude. Unless
// specified otherwise, this must conform to the
// <a href="http://www.unoosa.org/pdf/icg/2012/template/WGS_84.pdf">WGS84
// standard</a>. Values must be within normalized ranges.
message google.type.LatLng {
  // The latitude in degrees. It must be in the range [-90.0, +90.0].
  double latitude = 1;

  // The longitude in degrees. It must be in the range [-180.0, +180.0].
  double longitude = 2;
}

message google.type.LocalizedText {
  // Localized string in the language corresponding to `language_code`.
  string text = 1;

  // The text's BCP-47 language code, such as "en-US" or "sr-Latn".
  //
  // For more information, see
  // http://www.unicode.org/reports/tr35/#Unicode_locale_identifier.
  string language_code = 2;
}