Overview

Partners participating in the offers integration must complete the account setup for a Merchant or Entity (pilot) based integration step before they begin. The implementation, testing, and launch of the offers integration will be detailed in this guide. Read through this overview and offers policies before going through the integration steps.

Offers

The offers integration lets you relay structured information about merchant promotions and discounts applied to specific services at specific times. Offers are made up of the actual offer (percent-off, dollar-off ...), validity windows (specific times, days of the week ...), and applicable uses (the offer can only be used on certain services) as well of complex combinations of restrictions.

Examples of offers:

  • Half-off appetizers on Wednesdays and Thursdays in December from 12pm to 5pm
  • Buy one get one dessert free for Mother's Day dinner from 6pm to 10pm
  • $5 off a brunch entree every Sunday from 10am to 2pm
  • 10% off as walk-in offer combinable with 5% off for premium subscribers and 5% off if the user pays through your app.

In order for an offer to be included in the integration, it needs to fit within the technical data model as well as meet our eligibility requirements. Make sure to review our offers policies to ensure your integration is in compliance and for instructions on what to do with offers that don't fit the technical requirements.

Offers implementation

The offers integration consists of two feeds that will be uploaded daily or at frequency that ensures a high accuracy (meaning reduces staleness):

OfferFeed

Field NameTypeRequirementDescription
dataarray of object
(Offer)

Offer

Field NameTypeRequirementDescription
offer_idstring

Required

Unique ID of the offer. Required.
entity_idsarray of string

List of merchants who are participating in this offer.
add_on_offer_applicable_to_all_entitiesboolean

If true, this offer is applicable to all entities under the aggregator. Only applicable for add on offers.
offer_sourceenum
(OfferSource)

Required

An offer can be provided by the aggregator, an individual merchant, or even a third party as an add on. Required.
action_typeenum
(ActionType)

Required

The service that is providing the offer. An offer_id can belong to only one action_type. If an offer can be shared across multiple service types then duplicate offers with unique Ids are expected to be created for each service type. Required.
offer_modesarray of enum
(OfferMode)

Required

The methods the offer can be availed - walk in, reservation, online, etc. Required.
offer_categoryenum
(OfferCategory)

Required

The category of the offer. Required.
source_assigned_prioritynumber

Non-negative integer ([1-100], where 1 represents the highest priority) indicating the priority level of the offer assigned by the source. When multiple offers are available for the same merchant, this will be a signal for ranking offers. 0 would represent that the priority is not set.
offer_detailsobject
(OfferDetails)

Required

Details of the offer such as the discount, booking cost, etc. Required.
offer_restrictionsobject
(OfferRestrictions)

Required

Describes how the offer is restricted i.e. whether a subscription/payment instrument is required, whether this offer can be combined with other offers (and what types), etc. Required.
couponobject
(Coupon)

Details of a coupon. Required for offer_category: OFFER_CATEGORY_ADD_ON_COUPON_OFFER.
payment_instrumentobject
(PaymentInstrument)

Details of a payment instrument. Required for offer_category: OFFER_CATEGORY_ADD_ON_PAYMENT_OFFER.
subscriptionobject
(Subscription)

Details of a subscription. Required for offer_category: OFFER_CATEGORY_ADD_ON_SUBSCRIPTION_OFFER.
termsobject
(Terms)

Required

Terms and conditions of the offer. Required.
validity_periodsarray of object
(ValidityPeriod)

Required

The validity period of the offer. Describes what time period the offer is valid for including start and end times, days of the week, etc. Required.
offer_urlstring

URL to the merchant's offer page. Required for offer_category: OFFER_CATEGORY_BASE_OFFER.
image_urlstring

URL to the merchant's offer image.

OfferDetails

Field NameTypeRequirementDescription
offer_display_textstring

Required

The offer text the offer provider wants to display to customers on the search results page. Required.
oneOf
(offer_specification)

Required

Only one of the fields in this oneOf can be set.
max_discount_valueobject
(Money)

The maximum discount that can be availed. For example, 10% off up to $100.
min_spend_valueobject
(Money)

The minimum spend value to avail the discount. For example, 10% off when the total price is $100 or more.
booking_costobject
(Money)

The cost to book this offer. For example, $100 off the final bill when a table is reserved at the cost of $15.
booking_cost_unitenum
(FeeUnit)

The unit of the booking cost. For example, per person, per transaction.
convenience_feeobject
(Fee)

booking_cost_adjustableboolean

Whether the booking cost is adjustable i.e. the booking cost is subtracted from the final bill. For example: 30% off dinner with reservation. Cost to reserve $15 and it will be applied to the final bill. Hence final bill: Total Spent - 30% - $15
additional_feesarray of object
(AdditionalFee)

Additional fees that are charged to the user. Examples: convenience, handling etc.

Money

Represents an amount of money with its currency type.

Field NameTypeRequirementDescription
currency_codestring

The three-letter currency code defined in ISO 4217.
unitsstring

The whole units of the amount. For example if currencyCode is "USD", then 1 unit is one US dollar.
nanosnumber

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.

Fee

Field NameTypeRequirementDescription
unitenum
(FeeUnit)

typeenum
(FeeType)

oneOf
(cost)

Only one of the fields in this oneOf can be set.

MoneyRange

Field NameTypeRequirementDescription
min_amountobject
(Money)

max_amountobject
(Money)

AdditionalFee

Field NameTypeRequirementDescription
namestring

Required

The name of the additional fee. Examples: convenience fee, handling fee etc. Required.
feeobject
(Fee)

OfferRestrictions

Field NameTypeRequirementDescription
combinable_with_other_offersboolean

Whether this offer can be combined with other offers. When true, partners can specify what offers this offer can be combined with. If both combinable_offer_categories & combinable_offer_ids are set then any offer matching one of the conditions above will be combinable.
combinable_offer_categoriesarray of enum
(OfferCategory)

List of offer types that this offer can be combined with. For example, this offer may be combinable with other Coupons. If combinable_with_other_offers is true and this field is unset all types will be combinable.
combinable_offer_idsarray of string

List of offer_ids that this offer can be combined with. Some offers may only be combined with certain specific other offer_ids (can be considered parent offers). If combinable_with_other_offers is true and this field is unset all offer ids will be combinable.
inclusionsarray of object
(OfferCondition)

List of conditions that must be met for the offer to be valid (e.g., non-alcoholic drinks, food).
exclusionsarray of object
(OfferCondition)

List of conditions that would invalidate the offer (e.g., buffet, combo offers, and cocktails ).
min_guestnumber

The minimum number of people required to avail the offer.
food_offer_restrictionsobject
(FoodOfferRestrictions)

Restrictions specific to food offers.

OfferCondition

Field NameTypeRequirementDescription
descriptionstring

FoodOfferRestrictions

Field NameTypeRequirementDescription
meal_typesarray of enum
(MealType)

The meal types the offer can be applied to, such as lunch or dinner. If unset, the offer can be applied to all meal types.
restricted_to_certain_coursesboolean

Whether the offer can only be applied to certain courses.

Coupon

Field NameTypeRequirementDescription
textstring

The coupon text the offer provider wants to display to users.
codestring

Required

Coupon code required to redeem the offer. Required.

PaymentInstrument

Field NameTypeRequirementDescription
itemsarray of object
(PaymentInstrumentItem)

Required

List of payment instruments that can be used to avail the offer. Required.
provider_namestring

Required

Name of the payment instrument provider. Could be a banking partner, name of a bank, etc. For example: American Express, HDFC, ICICI. Required.

PaymentInstrumentItem

Field NameTypeRequirementDescription
typeenum
(PaymentInstrumentType)

Required

Type of the payment instrument. Required.
namestring

Required

Name of the payment instrument item like the name of the credit card. For example: HDFC Infinia, American Express Platinum. Required.

Subscription

Field NameTypeRequirementDescription
namestring

Required

The name of the subscription. Required.
subscription_auto_addedboolean

Whether the subscription is auto added when a user avails this offer
costobject
(Money)

Required

The cost of the subscription. Required.
subscription_durationobject
(Duration)

Required

How long the subscription is valid for at the subscription_cost. Required.
terms_and_conditions_urlstring

URL to the partner's terms and conditions relevant to this subscription.

Duration

Field NameTypeRequirementDescription
secondsstring

Signed seconds of the span of time. Must be from -315,576,000,000 to +315,576,000,000 inclusive. Note: these bounds are computed from: 60 sec/min * 60 min/hr * 24 hr/day * 365.25 days/year * 10000 years
nanosnumber

Signed fractions of a second at nanosecond resolution of the span of time. Durations less than one second are represented with a 0 seconds field and a positive or negative nanos field. For durations of one second or more, a non-zero value for the nanos field must be of the same sign as the seconds field. Must be from -999,999,999 to +999,999,999 inclusive.

Terms

Field NameTypeRequirementDescription
urlstring

URL to the partner's terms and conditions.
restricted_to_certain_usersboolean

Whether the offer is restricted to certain users.
terms_and_conditionsstring

Primary T&C text provided by the partner.
additional_terms_and_conditionsarray of string

Terms and conditions in addition to the primary T&C from the partner.

ValidityPeriod

Field NameTypeRequirementDescription
valid_periodobject
(ValidityRange)

The start and end timestamp that the offer is valid for. These times must represent distinct days i.e. the start time must be 00:00 (beginning of the day) and the end time must be 00:00 (exclusive) on the day the validity period ends.
time_of_dayarray of object
(TimeOfDayWindow)

Specifies the valid time interval on a given day and which days are available for the offer. For example: Monday: 10AM to 5PM Tuesday: 10AM to 2PM Tuesday: 5PM to 7PM Wed, Thur, Fri, Sat, Sun: 3PM to 7PM If none set, it means the offer is available for all time within valid_period.
time_exceptionsarray of object
(ValidTimeException)

Specifies exceptions to the above valid_period and valid_time_of_week

ValidityRange

A closed-open timestamp range.

Field NameTypeRequirementDescription
valid_from_timeobject
(Timestamp)

Required

The beginning time of the range (inclusive). Required.
valid_through_timeobject
(Timestamp)

The ending time of the range (exclusive). If not set, it means that this period is never ending. Optional.

Timestamp

Field NameTypeRequirementDescription
secondsstring

Represents seconds of UTC time since Unix epoch 1970-01-01T00:00:00Z. Must be from 0001-01-01T00:00:00Z to 9999-12-31T23:59:59Z inclusive.
nanosnumber

Non-negative fractions of a second at nanosecond resolution. Negative second values with fractions must still have non-negative nanos values that count forward in time. Must be from 0 to 999,999,999 inclusive.

TimeOfDayWindow

The TimeWindow object is a composite entity that describes a list of windows the user's order can be either placed or fulfilled.

Field NameTypeRequirementDescription
time_windowsobject
(TimeOfDayRange)

Required

The time window the order can be placed/fulfilled. Required.
day_of_weekarray of enum
(DayOfWeek)

The list of days in a week the windows are applied. If none set, it means that it applies for all days of the week. Optional.

TimeOfDayRange

A closed-open time range.

Field NameTypeRequirementDescription
open_timeobject
(TimeOfDay)

A Time indicating the beginning time of the day of the range (inclusive). If not set, it means 00:00:00. Optional.
close_timeobject
(TimeOfDay)

A Time indicating the ending time of the day of the range (exclusive). If not set, it means 23:59:59. Optional.

TimeOfDay

Field NameTypeRequirementDescription
hoursnumber

Hours of a day in 24 hour format. Must be greater than or equal to 0 and typically must be less than or equal to 23. An API may choose to allow the value "24:00:00" for scenarios like business closing time.
minutesnumber

Minutes of an hour. Must be greater than or equal to 0 and less than or equal to 59.
secondsnumber

Seconds of a minute. Must be greater than or equal to 0 and typically must be less than or equal to 59. An API may allow the value 60 if it allows leap-seconds.
nanosnumber

Fractions of seconds, in nanoseconds. Must be greater than or equal to 0 and less than or equal to 999,999,999.

ValidTimeException

Field NameTypeRequirementDescription
exceptional_periodobject
(ValidityRange)

The start and end timestamp that the offer is not valid for. These times must represent distinct days i.e. the start time must be 00:00 (beginning of the day) and the end time must be 00:00 (exclusive) on the day the exception period ends.

OfferSource

NameDescription
OFFER_SOURCE_UNSPECIFIED
OFFER_SOURCE_AGGREGATOR

ActionType

NameDescription
ACTION_TYPE_UNSPECIFIED
ACTION_TYPE_DINING

OfferMode

NameDescription
OFFER_MODE_OTHER
OFFER_MODE_WALK_IN
OFFER_MODE_FREE_RESERVATION
OFFER_MODE_PAID_RESERVATION
OFFER_MODE_ONLINE_ORDER

OfferCategory

Category of the offer. A base offer is a standard offer available to all customers such as 10% off spending over $100. A base offer restricted by a coupon or payment instrument will have the respective fields set. We also have add on x offers such as ADD_ON_PAYMENT_OFFER. Such offers can be added to other offers to gain additional discounts.

NameDescription
OFFER_CATEGORY_UNSPECIFIED
OFFER_CATEGORY_BASE_OFFER
OFFER_CATEGORY_ADD_ON_PAYMENT_OFFER
OFFER_CATEGORY_ADD_ON_COUPON_OFFER
OFFER_CATEGORY_ADD_ON_SUBSCRIPTION_OFFER

FeeUnit

NameDescription
FEE_UNIT_UNSPECIFIED
FEE_UNIT_PER_GUEST
FEE_UNIT_PER_TRANSACTION

FeeType

NameDescription
FEE_TYPE_UNSPECIFIED
FEE_TYPE_FIXED
FEE_TYPE_VARIABLE

MealType

NameDescription
MEAL_TYPE_UNSPECIFIED
MEAL_TYPE_BREAKFAST
MEAL_TYPE_LUNCH
MEAL_TYPE_DINNER

PaymentInstrumentType

NameDescription
PAYMENT_INSTRUMENT_TYPE_UNSPECIFIED
PAYMENT_INSTRUMENT_CREDIT_CARD
PAYMENT_INSTRUMENT_DEBIT_CARD
PAYMENT_INSTRUMENT_BANK_ACCOUNT
PAYMENT_INSTRUMENT_UPI
PAYMENT_INSTRUMENT_ONLINE_WALLET

DayOfWeek

Represents a day of the week.

NameDescription
DAY_OF_WEEK_UNSPECIFIEDThe day of the week is unspecified.
MONDAYMonday
TUESDAYTuesday
WEDNESDAYWednesday
THURSDAYThursday
FRIDAYFriday
SATURDAYSaturday
SUNDAYSunday

offer_specification

The discount can be a percentage or a fixed value subtracted from the total value. For example: 1. 10% off the final bill. 2. $15 off an order. Merchants can also offer custom discounts such as 'buy one get one free' through the relevant specification fields. Required.

Field NameTypeRequirementDescription
discount_percentnumber

Mutally exclusive with discount_value, other_offer_detail_text

Percentage of the bill that is discounted. [0, 100] For 1+1 or 50% off offers that are applicable to the whole meal (e.g. 1+1 buffet, 1+1 on entire bill, 1+1 on set menu), this value can be set to 50.
discount_valueobject
(Money)

Mutally exclusive with discount_percent, other_offer_detail_text

Fixed value of the discount.
other_offer_detail_textstring

Mutally exclusive with discount_percent, discount_value

Free-form text to describe the discount. For specific 1+1 offers (e.g. 1+1 drinks, +1 main course, 1+1 selected menu items), these details should be described here.

cost

Field NameTypeRequirementDescription
amountobject
(Money)

Mutally exclusive with amount_range

amount_rangeobject
(MoneyRange)

Mutally exclusive with amount

Feed upload

The Offers feed must be uploaded to the Generic feed SFTP server. Follow the How to use the Generic feed SFTP server tutorial for instructions and use the name set to google.offer in your descriptor file.

Upload frequency

In general, Google expect 1 feed upload per day. frequency may be increased or decreased depending on the frequency of offer updates on your side to ensure a consistently high precision. Consult with your Google POC.

The data will take a few hours before appearing on Google.

Offers categorization

  • OFFER_CATEGORY_BASE_OFFER: Offers that can be claimed independently without being combined with any other offer. This includes:
    • Flat discounts on the entire bill (e.g., 20% off)
    • Subscription offers (e.g., Free dessert with membership)
    • Payment offers in cases where there are no other base offers for the restaurant
  • Add-On Offers: Offers that require a base offer to be claimed. These include:
    • OFFER_CATEGORY_ADD_ON_PAYMENT_OFFER (e.g., Additional 10% off with specific credit card)
    • OFFER_CATEGORY_ADD_ON_COUPON_OFFER (e.g., Free drink with a specific coupon code)
    • OFFER_CATEGORY_ADD_ON_SUBSCRIPTION_OFFER (e.g., Additional 10% off for subscribers)

Other considerations:

  • When a restaurant has no Base Offer set, Add-On offers won't be displayed. If there's no Base Offer, any Payment, Subscription or Coupon Offer that can be claimed without needing to be added on to another offer must be tagged as OFFER_CATEGORY_BASE_OFFER.
    • Depending on the type, the relevant data for PaymentInstrument, Subscription, or Coupon must be set.
    • Partners must provide 2 copies of each of these offers to cover scenarios where they function as both Base Offers and Add-On Offers. The Add-On Offer copy can then be set for multiple restaurants using either entity_ids or add_on_offer_applicable_to_all_entities.
  • When a restaurant has multiple Base Offers that can be stackable, all the Base Offers should be tagged as OFFER_CATEGORY_BASE_OFFER, and Base Offers which are Payment, Subscription or Coupon offers should be sent additionally as the relevant Add-On Offer type.
  • ValidityPeriod should be used to activate Add-On offers as Base Offers only when there is no active Base Offer.

Example scenarios:

  • A restaurant offers 5% off when paying with a specific credit card and a free drink with a specific coupon code

    • 5% off credit card offer should be sent as 2 copies, one tagged as OFFER_CATEGORY_BASE_OFFER and one tagged as OFFER_CATEGORY_ADD_ON_PAYMENT_OFFER with the PaymentInstrument details included.
    • Free drink with a coupon code offer should be sent as OFFER_CATEGORY_ADD_ON_COUPON_OFFER with the Coupon details included.
  • A restaurant offers 10% off for walk-ins and 5% off when paying with a specific credit card, both of which can be combined.

    • 10% walk-in offer should be tagged as OFFER_CATEGORY_BASE_OFFER.
    • 5% off credit card offer should have 2 copies, with one tagged as OFFER_CATEGORY_BASE_OFFER, and one tagged as OFFER_CATEGORY_ADD_ON_PAYMENT_OFFER.
  • A restaurant offers 10% off only for lunch on weekdays, and 5% off anytime when paying with a specific credit card.

    • 10% off offer should have ValidityPeriod set to indicate only during the restaurant's lunch hours on weekdays.
    • 5% off credit card offer should be sent as 2 copies.
      • One copy should be tagged as OFFER_CATEGORY_BASE_OFFER with the PaymentInstrument details included. ValidityPeriod of should be set to exclude lunch hours on weekdays when the 10% off lunch offer is active
      • One copy should be tagged as OFFER_CATEGORY_ADD_ON_PAYMENT_OFFER with the PaymentInstrument details included.
    • All other Payment Offers for this restaurant should be tagged as OFFER_CATEGORY_ADD_ON_PAYMENT_OFFER.

Development & launch process

Throughout your integration, the Partner Portal will be able to assist you with information and feedback based on your development. The development process will follow this flow:

  • The integration will be first developed in the Sandbox environment. You should be using an export of production (or even production data directly) in the Google Sandbox environment. This helps ensure that your development catches all edge cases and allows Google to evaluate data quality and better assist you based on your data model.
  • Once you are uploading complete and daily Merchant, Services, and Deals feed consistently in the Google Sandbox environment the Google team will evaluate your feeds. Once the Google team provides approval, you can push your code to production and begin sending production data to the Google Production environment.
  • After you have fully tested the Production integration the Google team will test as well. Once all testing is complete, then your integration will launch.

Monitoring

To ensure a good user experience, Google will check that the offers provided are valid, correct and meet our policy criteria pre and post launch. To do so, Google will use a combination of human and automated review. The result of these reviews will be accessible in the Offer Dashboard of the Action Center (production only). The outcome of this monitoring might be used to affect the ranking of the offers.

Automated checks (Crawlers)

Google quality team implements crawlers. Crawlers are scripts that automate a web browser to perform some clicks and extract offer information, for quality testing purposes only.

Number of queries

For example, if we decided to send 5000 checks per day, it means that 5000 times per day (evenly distributed across the day, that is approximately one every 17 seconds), our crawler performs all of the following actions a regular user would perform:

  • Start from Google Search, and click the partner link.
  • Look for the offer information.
  • If the offer requires booking, it will continue toward the booking flow to confirm the offer is available at the specified time (no booking will be placed).

Web scraper detection

To ensure that the web scraper does not get banned (which may lead it to conclude the offers are not available) make sure your system allows our web scraper to query your page at all times. To identify our web scraper:

  • The web scraper User-Agent will contain the string "Google-Offers":
    • Example: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko; Google-Offers) Chrome/104.0.5112.101 Safari/537.36
  • You may also check if the calls come from google using reverse DNS as recommended in "Verifying Googlebot and other Google crawlers". In our specific case, the reverse DNS resolution follows this pattern: google-proxy-***-***-***-***.google.com.

Technical behavior

Caching

For purposes of reducing load on the partner website, our crawlers are generally configured to respect all standard HTTP caching headers present in the response. That means that for correctly configured websites we avoid repeatedly fetching content that changes rarely (e.g. JavaScript libraries). For more details on how to implement caching, read this HTTP caching documentation.