Services feed

message ServiceFeed {
  FeedMetadata metadata = 1;
  repeated Service service = 2;
}
// The definition of a service provided by a merchant.
message Service {
  // An opaque string from an aggregator partner which uniquely identifies a
  // merchant. (required)
  string merchant_id = 1;
  // An opaque string from an aggregator partner which uniquely identifies the
  // service. For dining this must be set to "1000". (required)
  string service_id = 2;
  // The name of the service, suitable for display to users, e.g. "Men's
  // haircut". (required)
  string name = 3;
  // The user-visible description of the service. Populating service description
  // is strongly recommended, but not strictly required.
  //
  // This field now supports both plain-text and HTML-like formatting rules to
  // display structural contents to end-users. Unlike plain text sections,
  // customized layouts can be created here using headings, paragraphs, lists
  // and some phrase tags. Please read the following instructions and notes
  // carefully to ensure you create the best user-experience.
  //
  // Supported HTML-like formatting tags:
  //
  // Heading tags: <h1>, <h2>, <h3>, <h4>, <h5>, <h6>
  //   Heading tags can be used to display titles and sub-titles. For example,
  //   <h1>Itinerary</h1> will display the inline text as the most important
  //   heading of the section. Note that any inner HTML tags, styles or
  //   attributes will be ignored. For example, <h1 style=".."> will be treated
  //   the same as <h1>. Only pure text wil be preserved.
  //
  // Paragraph tag: <p>:
  //   The paragraph tag can be used to highlight a detailed introduction or
  //   contents. Any inner tags, styles or attributes will be ignored, with a
  //   few exceptions: <br>, <strong> and <em>. Please see the phrase tag
  //   section below for more details.
  //
  // List tags: <ul>, <ol>, <li>
  //   The <ul> tag can be used with the <li> tag to display unordered lists,
  //   and the <ol> tag can be used with <li> to display ordered lists. This is
  //   a good way to display checklists, highlights, or any other lists that fit
  //   your use-cases.
  // Example: To show a list of features of a cruise trip:
  //   <ol>
  //     <li>Wonderful ocean view and chances to play with wildlife.</li>
  //     <li>Carefully designed travel arrangements and services.</li>
  //     <li>Gauranteed lowest price.</li>
  //   </ol>
  // Note that only <li> children under <ul> or <ol> tags will be converted. All
  // other children will be dropped. Also, any inner tags, attributes and styles
  // will be ignored; we only preserve pure text contents.
  //
  // Division tag: <div>
  //   All supported inner tags of the <div> tag will be parsed with the rules
  //   stated above, imply <div> tag itself does not mean any grouping or
  //   indenting here. Also, any inner attributes and styles will be ignored.
  //
  // Phrase tags: <br>, <strong>, <em>:
  //   Only the three tags mentioned above are supported. <br> can be used to
  //   break lines in paragraphs, and <strong>/<em> can be used to highlight
  //   important text. Any other phrase tags will be ignored.
  //
  // Unsupported tags:
  //   * <html>, <header>, and <body> tags are not allowed.
  //   * Any other tags not mentioned above are not supported (for example
  //     <table>, <td> ...).
  // Any URLs, anchors, and links will be stripped, and will never be displayed
  // to end-users. If you want to use photos to create a rich user experience,
  // please use the "related_media" field below to send your photo URLs.
  //
  // Important notes:
  //   * Try not to use other tags except for the supported ones mentioned
  //     above, because the contents within unsupported tags will be stripped,
  //     and may lead to an undesirable user experience.
  //   * Try avoid deep nested structures like more than 3 different heading
  //     levels or nested lists. Keeping the structure flat, simple, and
  //     straightforward, helps to create a better user experience.
  //   * If the currently supported layouts are not sufficient for your use
  //     cases, please reach out to the Reserve with Google team.
  //   * The recommended maximum size is 32,000 characters.
  //
  // (optional)
  string description = 4;
  // The price of the service. (optional, overridden when payment options or
  // ticket types present)
  Price price = 5;
  // Rules to book/cancel an appointment. (optional)
  SchedulingRules rules = 6;
  // Intake forms to customize the service. (optional)
  //
  // Deprecated. Please see intake_form and per_ticket_intake_form.
  repeated ServiceIntakeForm form = 7 [deprecated = true];

  // A form requesting additional information from the user when they book this
  // service. (optional)
  ServiceIntakeForm intake_form = 20;

  // A form requesting additional information from the user when they book this
  // service. This form must be filled out once for each ticket the user is
  // booking. (optional)
  ServiceIntakeForm per_ticket_intake_form = 21;

  // Enum to indicate the prepayment type.
  enum PrepaymentType {
    // By default we will assume that the prepayment is NOT_SUPPORTED.
    PREPAYMENT_TYPE_UNSPECIFIED = 0;
    // The user has to pay this service at the booking time.
    REQUIRED = 1;
    // The user can choose to pre-pay this service at the booking time or later,
    // but it is not required in order to book.
    OPTIONAL = 2;
    // The prepayment is not supported for this service.
    NOT_SUPPORTED = 3;
  }
  // Whether a prepayment is required, optional or not supported. (optional)
  PrepaymentType prepayment_type = 8;

  // The service's tax rate. If present this field overrides any tax_rate set at
  // the merchant level. An empty message (i.e. tax_rate { }) will reset the
  // applied tax rate to zero. (optional)
  TaxRate tax_rate = 9;

  // A list of ids referencing the payment options which can be used to pay
  // for this service. The actual payment options are defined at the Merchant
  // level, and can also be shared among multiple Merchants. (optional)
  repeated string payment_option_id = 10;

  // Defines how a deposit may be charged to the user. Can be overridden at the
  // availability level. (optional)
  Deposit deposit = 11;

  // Defines a no show fee that may be charged to the user. Can be overridden
  // at the availability level. (optional)
  NoShowFee no_show_fee = 12;

  // Indicates whether the user must provide a credit card in order to book this
  // service.
  // This value can be overridden at the availability level. (optional)
  RequireCreditCard require_credit_card = 13;

  // An action link related to this service.
  repeated ActionLink action_link = 14;

  enum ServiceType {
    SERVICE_TYPE_UNSPECIFIED = 0;
    SERVICE_TYPE_DINING_RESERVATION = 1;
    SERVICE_TYPE_FOOD_ORDERING = 2;
    SERVICE_TYPE_EVENT_TICKET = 3;
    SERVICE_TYPE_TRIP_TOUR = 4;
  }

  // The predefined type of this service. This is required when action_link
  // exists in the Service.
  ServiceType type = 15;

  // Types of tickets that can be booked/purchased for this service. Only
  // supported in order based booking API, see
  // https://developers.google.com/maps-booking/guides/partner-implementing-booking-server-1a
  // (optional)
  repeated TicketType ticket_type = 16;

  // Photos related to this service. Google will crawl these media to ensure
  // that they are displayed correctly to end-users. (optional)
  repeated RelatedMedia related_media = 17;

  // Service attribute values that apply to this service (optional).
  // Each Service may have zero or more values for each service attribute
  // defined in the corresponding Merchant.
  repeated ServiceAttributeValueId service_attribute_value_id = 18;

  // Rules related to joining the waitlist. Should be populated if the service
  // and merchant support waitlist functionality. Should not be populated
  // otherwise.
  WaitlistRules waitlist_rules = 19;
}
// The price of a service or a fee.
message Price {
  // The price in micro-units of the currency.
  // For example: 1.95 USD is 1950000 in micro-units.
  // If your price contains fractions of the smallest currency unit, then it
  // will be rounded using nearest even rounding (e.g. 2.5 cents rounded
  // to 2 cents, 3.5 cents rounded to 4 cents, 0.5 cents rounded to 0 cents,
  // 2.51 cents rounded to 3 cents). (required)
  int64 price_micros = 1;
  // The currency of the price that is defined in ISO 4217. (required)
  string currency_code = 2;
  // An optional and opaque string that identifies the pricing option that is
  // associated with the extended price. (optional)
  string pricing_option_tag = 3;
}
// The scheduling rules for a service.
message SchedulingRules {
  // The duration (in seconds) from when the last booking can be made to
  // when the availability slot starts or ends.
  //
  // If "min_advance_booking" is set, the last bookable time is calculated as
  // (<slot start time> - "min_advance_booking").
  // If "min_booking_buffer_before_end_time" is set, the last bookable time is
  // calculated as (<slot end time> - "min_booking_buffer_before_end_time").
  // Note that the value of "min_booking_buffer_before_end_time" must be
  // positive if set.
  // If both are unset, the slot is bookable until the slot begin time.
  //
  // Examples:
  //  * A haircut that needs to be booked at least 1 hour before the start time.
  //      'scheduling_rules{ min_advance_booking: 3600 ...}`
  //
  //  * A museum where the last ticket can be purchased 30 mins before closing:
  //     'scheduling_rules{ min_booking_buffer_before_end_time: 1800 ...}'
  //
  //  * A movie ticket that needs to be purchased before the start time.
  //        'scheduling_rules{ ...}' (leave this field empty)
  // (optional)
  oneof min_booking_buffer {
    // The duration (in seconds) from when the last booking can be made to
    // when the availability slot starts.
    int64 min_advance_booking = 1;

    // The duration (in seconds) from when the last booking can be made to
    // when the availability slot ends. If this field is set, the
    // "admission_policy" field must be set to TIME_FLEXIBLE to indicate that
    // users can use the purchased tickets after slots start.
    int64 min_booking_buffer_before_end_time = 6;
  }

  // The minimum advance notice in seconds required to cancel a booked
  // appointment online. (optional)
  int64 min_advance_online_canceling = 2;

  // The fee for canceling within the minimum advance notice period.
  Price late_cancellation_fee = 3 [deprecated = true];

  // The fee for no-show without canceling.
  Price noshow_fee = 4 [deprecated = true];

  // The admission policy of this service.
  enum AdmissionPolicy {
    // Unused.
    ADMISSION_POLICY_UNSPECIFIED = 0;

    // Customers are required to be present at the start time of the
    // availability slot, and the service is expected to finish at the
    // end time of the slot.
    // Examples of TIME_STRICT use cases:
    //   * A tour that starts at 9am that requires all attendees to arrive
    //     at the start time, and returns at around 12pm.
    //   * A haircut reservation at 3pm on Saturday that will take approximately
    //   30 minutes.
    //   * A fitness class from 6pm to 8pm.
    TIME_STRICT = 1;

    // Customers can arrive at any time between the start and end time of the
    // availability slot to use this booking.
    //
    // Examples of TIME_FLEXIBLE use cases:
    //   * A museum ticket that can be used during any time on the purchase
    //     date.
    //   * An afternoon admission to an amusement park that can be used from
    //     12pm to 9pm.
    TIME_FLEXIBLE = 2;

    // Customers need to arrive at the merchant at the start time of the
    // availability slot but can leave any time they want.
    //
    // For example, in the museum admission scenario, a timed entry ticket
    // for 10am requires the user to be at the museum at 10am. The start time of
    // availability slots for this service represents the designated entry
    // time. The end time, however, is used solely as a key to identify the
    // availability slot for booking.
    TIMED_ENTRY_WITH_FLEXIBLE_DURATION = 3;
  }

  // The admission policy that applied to this service. If unset, defaults to
  // TIME_STRICT. (optional)
  AdmissionPolicy admission_policy = 5;
}
// A tax rate applied when charging the user for a service, and which can be set
// on either a per merchant, or per service basis.
message TaxRate {
  // A tax rate in millionths of one percent, effectively giving 6 decimals of
  // precision. For example, if the tax rate is 7.253%, this field should be set
  // to 7253000.
  //
  // If this field is left unset or set to 0, the total price charged to a user
  // for any service provided by this merchant is the exact price specified by
  // Service.price. The service price is assumed to be exempt from or already
  // inclusive of applicable taxes. Taxes will not be shown to the user as a
  // separate line item.
  //
  // If this field is set to any nonzero value, the total price charged to a
  // user for any service provided by this merchant will include the service
  // price plus the tax assessed using the tax rate provided here. Fractions of
  // the smallest currency unit (for example, fractions of one cent) will be
  // rounded using nearest even rounding. Taxes will be shown to the user as a
  // separate line item. (required)
  int32 micro_percent = 1;
}
// Defines a field that is included in a ServiceIntakeForm.
message ServiceIntakeFormField {
  // A string from an aggregator partner which uniquely identifies a form field.
  // This id should be the same as the id in the corresponding form field
  // answer and must be unique across both the service level and per ticket
  // intake forms. (required)
  string id = 5;

  // Enum to indicate the type of field.
  enum FieldType {
    // Fields of unspecified or unknown type will be ignored.
    FIELD_TYPE_UNSPECIFIED = 0;
    // A one-line input field for text.
    SHORT_ANSWER = 1;
    // A multi-line input field for text.
    PARAGRAPH = 2;
    // A set of radio buttons that requires one choice from many options.
    MULTIPLE_CHOICE = 3;
    // One or more enumerated items with checkboxes.
    CHECKBOXES = 4;
    // A selection from a dropdown.
    DROPDOWN = 5;
    // A yes/no button.
    BOOLEAN = 6;
  }

  // The type of this field. (required)
  FieldType type = 1;

  // The text shown to the user for this field. (required)
  string label = 2;

  // For MULTIPLE_CHOICE, CHECKBOXES, or DROPDOWN, the values to enumerate.
  // (optional)
  repeated string value = 3;

  // Indicates whether an answer to this field is required by a user. (optional)
  bool is_required = 4;
}
// Defines an intake form that customizes the service provided by a merchant.
message ServiceIntakeForm {
  // Fields that will be displayed to the user. (required)
  repeated ServiceIntakeFormField field = 1;

  // If true, this form will be shown to first time customers.
  // Deprecated. This functionality is not supported for intake forms.
  bool first_time_customers = 2 [deprecated = true];

  // If true, this form will be shown to repeat customers.
  // Deprecated. This functionality is not supported for intake forms.
  bool returning_customers = 3 [deprecated = true];
}
// A deposit that the user may be charged or have a hold on their credit card
// for.
message Deposit {
  // Deposit amount.
  Price deposit = 1;

  // Minimum advance cancellation for the deposit.
  int64 min_advance_cancellation_sec = 2;

  // Defines how the deposit is determined from the availability.
  PriceType deposit_type = 3;
}
// A fee that a user may be charged if they have made a booking but do not
// show up.
message NoShowFee {
  // The amount the user may be charged if they do not show up for their
  // reservation.
  Price fee = 1;

  // Defines how the fee is determined from the availability.
  PriceType fee_type = 3;
}
// Defines how a total price is determined from an availability.
enum PriceType {
  // The price is for a fixed amount. This is the default value if the field is
  // not set.
  FIXED_RATE_DEFAULT = 0;
  // The price specified is per person, and the total price is calculated
  // according to the party size specified in Resources as
  // price_micros * party_size. A PER_PERSON price must be accompanied by a
  // party size in the availability resources. If it is not, a party size of one
  // is used.
  PER_PERSON = 1;
}
// Defines whether a credit card is required in order to book an appointment.
enum RequireCreditCard {
  // The credit card requirement is not explicitly specified and the
  // behaviour is identical to the one specified for CONDITIONAL.
  REQUIRE_CREDIT_CARD_UNSPECIFIED = 0;

  // Google will require a credit card for the booking if any of the following
  // conditions are met:
  // * the availability has a price and the prepayment_type is REQUIRED
  // * the no_show_fee is set
  // * the deposit field is set.
  REQUIRE_CREDIT_CARD_CONDITIONAL = 1;

  // A credit card is always required in order to book this availability
  // regardless of other field values.
  REQUIRE_CREDIT_CARD_ALWAYS = 2;
}
// An action URL with associated language, list of countries restricted to, and
// optional platform that indicates which platform this action should be
// performed on.
message ActionLink {
  // The entry point URL for this action link.
  string url = 1;

  // The BCP-47 language tag identifying the language in which the content
  // from this URI is available.
  string language = 2;

  // ISO 3166-1 alpha-2 country code. Leave empty for unrestricted visibility.
  repeated string restricted_country = 3;

  // The platform that this action should be performed on. If this field is
  // unset, ACTION_PLATFORM_WEB_APPLICATION will be used as fallback.
  ActionPlatform platform = 4;
}
// The platform that the action is performed on. Web application is the general
// fallback. It is recommended to have at least one ActionLink with
// ACTION_PLATFORM_WEB_APPLICATION. Links with Android and iOS as platform are
// only used on the respective system.
enum ActionPlatform {
  // The platform is unspecified.
  ACTION_PLATFORM_UNSPECIFIED = 0;

  // The action platform is web in general.
  ACTION_PLATFORM_WEB_APPLICATION = 1;

  // The action platform is web on mobile devices.
  ACTION_PLATFORM_MOBILE_WEB = 2;

  // The action platform is Android OS.
  ACTION_PLATFORM_ANDROID = 3;

  // The action platform is iOS.
  ACTION_PLATFORM_IOS = 4;
}
// TicketType is used to differentiate among tickets (where a ticket can be a
// spot on a raft trip, an admission to a museum, etc.) with different prices
// and/or availabilities due to different user types or different service
// attributes.
message TicketType {
  // The ticket id is used to differentiate among different ticket types of the
  // same service, and is only expected to be unique within a service.
  string ticket_type_id = 1;

  // This can be user visible, e.g., “adult”, "child", “veteran”, “Row J”, etc.
  string short_description = 2;

  // The price of a single ticket of this type, exclusive of any taxes. The tax
  // rate of Service is applied to its tickets.
  Price price = 3;
}
// Photos related to this service. Google will crawl these media to ensure
// that they are displayed correctly to end-users. (optional)
message RelatedMedia {
  // URL of this media source. Google will crawl the media hosted at this URL.
  string url = 1;

  // Type of this media source.
  MediaType type = 2;

  // Enum to indicate the type of this media source. Only photos are supported.
  // Please reach out to the Reserve with Google team if other media beyond
  // photos need to be supported.
  enum MediaType {
    // Unused.
    TYPE_UNSPECIFIED = 0;
    // Indicates the media provided by the url is a photo.
    PHOTO = 1;
  }

  // Caption of the media, only plain text is supported. Any HTML components
  // will be stripped. (optional)
  string caption = 3;

  // 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. (optional)
  Attribution attribution = 4;

  // Attribution information for this media.
  message Attribution {
    // The text to give credit to the photographer or agency. This text will be
    // displayed together with the source media. Note that only plain text is
    // supported for this field, any HTML components will be stripped (hyperlink
    // based attribution is not supported).
    string text = 1;
  }
}
// Identifies a particular value of a service attribute to be applied to a
// Service.
message ServiceAttributeValueId {
  // ID of an attribute as defined in Merchant.service_attribute, e.g.
  // "service-type".
  string attribute_id = 1;

  // ID of the value for this attribute, e.g. "haircut". Must match a value_id
  // in the service attribute definition.
  string value_id = 2;
}

// Rules related to joining the waitlist.
message WaitlistRules {
  // Required. Must be a positive integer for services providing waitlist
  // functionality. If the service or merchant does not provide waitlist
  // functionality, this must not be populated.
  int32 min_party_size = 1;
  // Required. Must be a positive integer for services providing waitlist
  // functionality. If the service or merchant does not provide waitlist
  // functionality, this must not be populated.
  int32 max_party_size = 2;
  // If true, the user will be able to send a free-form additional text request
  // when joining the waitlist for this service.
  bool supports_additional_request = 3;
}