## Create and upload POI feeds

When creating and uploading POI feeds, follow these instructions:

- Follow the spec described in the [POI feed](https://developers.google.com/actions-center/verticals/local_vss/reference/poi-feed-doc.md.txt#feed_specifications) for POI data files. We recommend using unique POI data file names for each upload. Include a timestamp in the filename, for example, `POI_1633621547.json`.
- Upload feeds to the local POI SFTP server daily as full refreshes.
- You can find SFTP server details in the [Configuration \> Feeds](https://partnerdash.google.com/apps/reservewithgoogle/configuration/feeds) section of the Partner Portal.

![Selecting feed servers](https://developers.google.com/static/actions-center/images/sftp_local_poi.png)

- Validate your POI feed before uploading using the [POI Feed Validator](https://developers.google.com/actions-center/verticals/local_vss/reference/poi-feed-validator.md.txt).
- View feed ingestion status in the [Ingestion \> History](https://actionscenter.google.com/ingestions) section of the Partner Portal.

## File Packaging Guidelines

To ensure successful ingestion, adhere to the following packaging
requirements:

- **Single Aggregated JSON Archive (Required)**: Combine all entity records into one single JSON file. We recommend compressing it into a single GZIP archive, and uploading it.
- **Anti-Pattern Warning**: Do not use one file per entity or multiple files separated by country in the same archive. This approach is not supported and will cause extraction failures.

### Multi-lingual Support

The Point of Interest feed supports providing localized content for specific
fields. The following fields are of type `Text` and support localization:

- `name`
- `description`
- `display_address`

To provide content in multiple languages, you must specify a `default_locale` in
the field and provide the localized strings in the `localizations` list.
Provide all localizations for an entity in a single POI entry. Don't split a
single entity among multiple language JSON files.

Example:

```json
"name": {
  "localizations": [
    {
      "locale": "en",
      "text": "Tasty Bites Test Restaurant"
    },
    {
      "locale": "es",
      "text": "Restaurante de prueba Tasty Bites"
    }
  ],
  "default_locale": "en"
}
```

### Image Guidelines

> [!NOTE]
> **Note:** All images added to the feed follow these guidelines:

- Format: Must be JPEG, PNG, or WebP.
- Max File Size: Under 30 MB per image.
- Max Dimensions: Less than 75 Megapixels total (width x height \< 75,000,000).
- URL Type: Direct path to the image asset (e.g., ends in .jpg).
- Permissions: Ensure the hosting server allows access to Googlebot or Crawlers and has no robots.txt blocking the image directories.
- Safe Search: Images must comply with Google's [safe search policies.](https://support.google.com/websearch/answer/10688017)

## Feed Specifications

### Field Requirements

### VssPoi

Represents a single Point of Interest (POI) entity e.g. a hotel or
restaurant.

| Field Name | Type | Requirement | Description |
|---|---|---|---|
| `poi_id` | string | Required | Required. A string generated by the partner that identifies a POI. |
| `name` | object [`(Text)`](https://developers.google.com/actions-center/verticals/local_vss/reference/poi-feed-doc.md.txt#description-table-madden.vss_poi_feed.Text) | Required | Required. The name of the POI. |
| `telephone` | string | <br /> | The contact telephone number of the POI including its country and area codes, e.g. +14567891234. |
| `url` | string | <br /> | The url of the POI's public website. Note: This will be used just for matching purposes, not for display. |
| `location` | object [`(GeoCoordinates)`](https://developers.google.com/actions-center/verticals/local_vss/reference/poi-feed-doc.md.txt#description-table-madden.vss_poi_feed.GeoCoordinates) | Required | Required. The location of the POI. |
| `display_address` | object [`(Text)`](https://developers.google.com/actions-center/verticals/local_vss/reference/poi-feed-doc.md.txt#description-table-madden.vss_poi_feed.Text) | <br /> | The address displayed on the UI. |
| `images` | array of object [`(Image)`](https://developers.google.com/actions-center/verticals/local_vss/reference/poi-feed-doc.md.txt#description-table-madden.vss_poi_feed.Image) | <br /> | Images of the POI. Max number of images: 5. |
| `rating` | number | <br /> | Average rating for the POI. |
| `num_ratings` | number | <br /> | The number of contributing ratings for the `rating` field. |
| `rating_scale` | number | <br /> | The rating scale used for the `rating` field. If max rating is 5, then rating_scale is 5. |
| `category` | enum [`(Category)`](https://developers.google.com/actions-center/verticals/local_vss/reference/poi-feed-doc.md.txt#description-table-madden.vss_poi_feed.VssPoi.Category) | Required | Required. Represents the category of the POI. |
| `description` | object [`(Text)`](https://developers.google.com/actions-center/verticals/local_vss/reference/poi-feed-doc.md.txt#description-table-madden.vss_poi_feed.Text) | <br /> | A description of the POI. |
|   | oneOf [`(additional_data)`](https://developers.google.com/actions-center/verticals/local_vss/reference/poi-feed-doc.md.txt#description-table-madden.vss_poi_feed.VssPoi.additional_data) | Required | Only one of the fields in this oneOf can be set. |

### Text

Represents a text with localizations.

| Field Name | Type | Requirement | Description |
|---|---|---|---|
| `localizations` | array of object [`(LocalizedString)`](https://developers.google.com/actions-center/verticals/local_vss/reference/poi-feed-doc.md.txt#description-table-madden.vss_poi_feed.Text.LocalizedString) | <br /> | The localized strings. |
| `default_locale` | string | <br /> | The locale to use as the default language it must be present in the localizations. |

### LocalizedString

Represents a localized string.

| Field Name | Type | Requirement | Description |
|---|---|---|---|
| `locale` | string | <br /> | The text's language tag, such as "en", "en-US" or "sr-Latn". |
| `text` | string | <br /> | The text in the specified locale. |

### GeoCoordinates

The Geo data of a location, including latitude, longitude, and address.

| Field Name | Type | Requirement | Description |
|---|---|---|---|
| `latitude` | number | <br /> | \[-90, +90\] degrees (inclusive). Required if longitude is set, otherwise nice to have. |
| `longitude` | number | <br /> | \[-180, +180\] degrees (inclusive). Required if latitude is set, otherwise nice to have. |
|   | oneOf [`(addresses)`](https://developers.google.com/actions-center/verticals/local_vss/reference/poi-feed-doc.md.txt#description-table-madden.vss_poi_feed.GeoCoordinates.addresses) | Required | Only one of the fields in this oneOf can be set. |

### PostalAddress

The postal address for the location.

| Field Name | Type | Requirement | Description |
|---|---|---|---|
| `country` | string | Required | Required. The country, using ISO 3166-1 alpha-2 country code, e.g. "US". |
| `locality` | string | Required | Required. The locality/city, e.g. "Mountain View". |
| `region` | string | <br /> | The region/state/province, e.g. "CA". This field is only required in countries where region is commonly a part of the address. (optional) |
| `postal_code` | string | Required | Required. The postal code, e.g. "94043". |
| `street_address` | string | Required | Required. The street address, e.g. "1600 Amphitheatre Pkwy". |

### Image

Represents an image of the Point of Interest (POI).

| Field Name | Type | Requirement | Description |
|---|---|---|---|
| `url` | string | <br /> | The url of the image. Google will crawl the media hosted at this URL. Max length: 2000. |
| `alt_text` | object [`(Text)`](https://developers.google.com/actions-center/verticals/local_vss/reference/poi-feed-doc.md.txt#description-table-madden.vss_poi_feed.Text) | <br /> | The alternative text to be used for accessibility. |

### HotelData

Hotel specific feed data.

| Field Name | Type | Requirement | Description |
|---|---|---|---|
| `hotel_star_class` | number | <br /> | The official hotel class star value. Can be used in a label like "5-star hotel." This value is expected to be an integer between 0 and 5. A rating of 0 should be used if a rating is unavailable or not specified. When set to 0, no star class will be displayed on the UI for users. |
| `brand_ids` | array of string | <br /> | The brands that can display this hotel. If this field is empty, the hotel can be displayed under any of the brands associated with the feed. |

### LocalData

Establishment specific feed data.

| Field Name | Type | Requirement | Description |
|---|---|---|---|
| `business_hours` | object [`(BusinessHours)`](https://developers.google.com/actions-center/verticals/local_vss/reference/poi-feed-doc.md.txt#description-table-madden.vss_poi_feed.BusinessHours) | <br /> | The regular business hours of the establishment. |
| `price_range` | object [`(PriceRange)`](https://developers.google.com/actions-center/verticals/local_vss/reference/poi-feed-doc.md.txt#description-table-madden.vss_poi_feed.PriceRange) | <br /> | Price range of the services offered by the establishment. |
| `establishment_category` | object [`(Text)`](https://developers.google.com/actions-center/verticals/local_vss/reference/poi-feed-doc.md.txt#description-table-madden.vss_poi_feed.Text) | <br /> | The type of establishment. |
| `brand_landing_pages` | array of object [`(BrandLandingPages)`](https://developers.google.com/actions-center/verticals/local_vss/reference/poi-feed-doc.md.txt#description-table-madden.vss_poi_feed.BrandLandingPages) | Required | Required. The brand landing pages. At least one must be provided. |

### BusinessHours

Represents the time periods that this location is open for business.
Holds a collection of \[TimeRange\]\[madden.vss_poi_feed.TimeRange\]
instances.

Example: Open on Saturdays from 09:00-12:00 and 13:00-17:00:

time_ranges {
open_day: SATURDAY
open_time: { hours: 9, minutes: 0 }
close_day: SATURDAY
close_time: { hours: 12, minutes: 0 }
}
time_rages {
open_day: SATURDAY
open_time: { hours: 13, minutes: 0 }
close_day: SATURDAY
close_time: { hours: 17, minutes: 0 }
}

Example: Open on Saturdays from 21:00 to Sunday 02:00:

time_ranges {
open_day: SATURDAY
open_time: { hours: 21, minutes: 0 }
close_day: SUNDAY
close_time: { hours: 2, minutes: 0 }
}

| Field Name | Type | Requirement | Description |
|---|---|---|---|
| `time_ranges` | array of object [`(TimeRange)`](https://developers.google.com/actions-center/verticals/local_vss/reference/poi-feed-doc.md.txt#description-table-madden.vss_poi_feed.TimeRange) | <br /> | A collection of times that this POI is open for business. Each period represents a range of hours when the POI is open during the week. |

### TimeRange

Represents a span of time that the POI is open, starting on the
specified open day/time and closing on the specified close day/time.

The closing time must occur after the opening time, for example later in the
same day, or on a subsequent day.

| Field Name | Type | Requirement | Description |
|---|---|---|---|
| `open_day` | enum [`(DayOfWeek)`](https://developers.google.com/actions-center/verticals/local_vss/reference/poi-feed-doc.md.txt#description-table-google.type.DayOfWeek) | <br /> | The open day of the time range. |
| `open_time` | object [`(TimeOfDay)`](https://developers.google.com/actions-center/verticals/local_vss/reference/poi-feed-doc.md.txt#description-table-google.type.TimeOfDay) | <br /> | The open time of the time range. |
| `close_day` | enum [`(DayOfWeek)`](https://developers.google.com/actions-center/verticals/local_vss/reference/poi-feed-doc.md.txt#description-table-google.type.DayOfWeek) | <br /> | The close day of the time range. |
| `close_time` | object [`(TimeOfDay)`](https://developers.google.com/actions-center/verticals/local_vss/reference/poi-feed-doc.md.txt#description-table-google.type.TimeOfDay) | <br /> | The close time of the time range. |

### TimeOfDay

| Field Name | Type | Requirement | Description |
|---|---|---|---|
| `hours` | number | <br /> | 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. |
| `minutes` | number | <br /> | Minutes of an hour. Must be greater than or equal to 0 and less than or equal to 59. |
| `seconds` | number | <br /> | 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. |
| `nanos` | number | <br /> | Fractions of seconds, in nanoseconds. Must be greater than or equal to 0 and less than or equal to 999,999,999. |

### PriceRange

Price range of the services offered by the POI.

| Field Name | Type | Requirement | Description |
|---|---|---|---|
| `min_price` | object [`(Money)`](https://developers.google.com/actions-center/verticals/local_vss/reference/poi-feed-doc.md.txt#description-table-google.type.Money) | <br /> | The minimum price of the services offered by the POI. |
| `max_price` | object [`(Money)`](https://developers.google.com/actions-center/verticals/local_vss/reference/poi-feed-doc.md.txt#description-table-google.type.Money) | <br /> | The maximum price of the services offered by the POI. |

### Money

Represents an amount of money with its currency type.

| Field Name | Type | Requirement | Description |
|---|---|---|---|
| `currency_code` | string | <br /> | The three-letter currency code defined in ISO 4217. |
| `units` | number | <br /> | The whole units of the amount. For example if `currencyCode` is `"USD"`, then 1 unit is one US dollar. |
| `nanos` | number | <br /> | 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. |

### BrandLandingPages

The Localized brand landing pages for a single Point of Interest (POI).

| Field Name | Type | Requirement | Description |
|---|---|---|---|
| `brand_id` | string | Required | Required. The brand this configuration applies to. |
| `localized_landing_pages` | array of object [`(LocalizedLandingPage)`](https://developers.google.com/actions-center/verticals/local_vss/reference/poi-feed-doc.md.txt#description-table-madden.vss_poi_feed.BrandLandingPages.LocalizedLandingPage) | <br /> | The localized landing pages. The url and locales fields values must be unique across all the localized landing pages. |
| `default_url` | string | Required | Required. The default landing page url to be used when none of the localized landing pages matches the user's language. |

### LocalizedLandingPage

Localized landing page for the Point of Interest (POI).

| Field Name | Type | Requirement | Description |
|---|---|---|---|
| `url` | string | <br /> | The url of the landing page. Max length: 2000. |
| `locales` | array of string | <br /> | Restricts this page to users with the specified language preference. Must contain language tags, such as "en", "en-US" or "sr-Latn". |

### Category

Represents the category of the POI.
It should match the `additional_data` oneof field below.

| Name | Description |
|---|---|
| `UNKNOWN_CATEGORY` |   |
| `HOTEL` |   |
| `LOCAL` |   |

### DayOfWeek

Represents a day of the week.

| Name | Description |
|---|---|
| `DAY_OF_WEEK_UNSPECIFIED` | The day of the week is unspecified. |
| `MONDAY` | Monday |
| `TUESDAY` | Tuesday |
| `WEDNESDAY` | Wednesday |
| `THURSDAY` | Thursday |
| `FRIDAY` | Friday |
| `SATURDAY` | Saturday |
| `SUNDAY` | Sunday |

### additional_data

Required. Category specific fields.
It should match the `category` field above.

| Field Name | Type | Requirement | Description |
|---|---|---|---|
| `hotel_data` | object [`(HotelData)`](https://developers.google.com/actions-center/verticals/local_vss/reference/poi-feed-doc.md.txt#description-table-madden.vss_poi_feed.HotelData) | Mutally exclusive with `local_data` | Hotel specific fields. |
| `local_data` | object [`(LocalData)`](https://developers.google.com/actions-center/verticals/local_vss/reference/poi-feed-doc.md.txt#description-table-madden.vss_poi_feed.LocalData) | Mutally exclusive with `hotel_data` | Local specific fields. |

### addresses

Required. Address for a location.

| Field Name | Type | Requirement | Description |
|---|---|---|---|
| `address` | object [`(PostalAddress)`](https://developers.google.com/actions-center/verticals/local_vss/reference/poi-feed-doc.md.txt#description-table-madden.vss_poi_feed.PostalAddress) | <br /> | Postal address of the location. |

## Definitions

> [!NOTE]
> **Note:** The Point of Interest (POI) feed spec is defined in protobuffer format, however we recommend uploading the feeds in JSON format.

### VssPoiFeed Definition

```protobuf
// Represents a Point of Interest (POI) data feed provided by a partner.
export message VssPoiFeed {
  // The POIs in the feed.
  repeated VssPoi data = 1;
}
```

### VssPoi Definition

```protobuf
// Represents a single Point of Interest (POI) entity e.g. a hotel or
// restaurant.
export message VssPoi {
  // Required. A string generated by the partner that identifies a POI.
  string poi_id = 1;

  // The entity name, telephone, url and location are used to support
  // matching partner inventory with entities already present on Google.

  // Required. The name of the POI.
  Text name = 2;

  // The contact telephone number of the POI including its country and
  // area codes, e.g. +14567891234.
  string telephone = 3 [(datapol.semantic_type) = ST_PHONE_NUMBER];

  // The url of the POI's public website.
  // Note: This will be used just for matching purposes, not for display.
  string url = 4;

  // Required. The location of the POI.
  GeoCoordinates location = 5;

  // The address displayed on the UI.
  Text display_address = 17;

  // Images of the POI.
  // Max number of images: 5.
  repeated Image images = 6;

  // Average rating for the POI.
  float rating = 12;

  // The number of contributing ratings for the `rating` field.
  int64 num_ratings = 13;

  // The rating scale used for the `rating` field. If max rating is 5, then
  // rating_scale is 5.
  int32 rating_scale = 14;

  // Represents the category of the POI.
  // It should match the `additional_data` oneof field below.
  export enum Category {


    LOCAL = 4;
  }

  // Required. Represents the category of the POI.
  Category category = 9;

  // A description of the POI.
  Text description = 16;

  // Required. Category specific fields.
  // It should match the `category` field above.
  oneof additional_data {


    // Local specific fields.
    LocalData local_data = 15;
  }

}
```

### Text Definition

```protobuf
// Represents a text with localizations.
message Text {
  // Represents a localized string.
  message LocalizedString {
    // The text's language tag, such as "en", "en-US" or "sr-Latn".
    string locale = 1;

    // The text in the specified locale.
    string text = 2;
  }

  // The localized strings.
  repeated LocalizedString localizations = 1;

  // The locale to use as the default language it must be present in the
  // localizations.
  string default_locale = 2;
}
```

### GeoCoordinates Definition

```protobuf
// The Geo data of a location, including latitude, longitude, and address.
message GeoCoordinates {
  option (datapol.msg_semantic_type) = ST_LOCATION;

  // [-90, +90] degrees (inclusive).
  // Required if longitude is set, otherwise nice to have.
  double latitude = 1;

  // [-180, +180] degrees (inclusive).
  // Required if latitude is set, otherwise nice to have.
  double longitude = 2;

  // Required. Address for a location.
  oneof addresses {
    // Postal address of the location.
    PostalAddress address = 3;

  }
}
```

### PostalAddress Definition

```protobuf
// The postal address for the location.
message PostalAddress {
  option (datapol.msg_semantic_type) = ST_LOCATION;

  // Required. The country, using ISO 3166-1 alpha-2 country code, e.g. "US".
  string country = 1;

  // Required. The locality/city, e.g. "Mountain View".
  string locality = 2;

  // The region/state/province, e.g. "CA". This field is only required in
  // countries where region is commonly a part of the address. (optional)
  string region = 3;

  // Required. The postal code, e.g. "94043".
  string postal_code = 4;

  // Required. The street address, e.g. "1600 Amphitheatre Pkwy".
  string street_address = 5;
}
```

### Image Definition

```protobuf
// Represents an image of the Point of Interest (POI).
export message Image {
  // The url of the image. Google will crawl the media hosted at this URL.
  // Max length: 2000.
  string url = 1;

  // The alternative text to be used for accessibility.
  Text alt_text = 2;
}
```

### LocalData Definition

```protobuf
// Establishment specific feed data.
message LocalData {
  // The regular business hours of the establishment.
  BusinessHours business_hours = 1;

  // Price range of the services offered by the establishment.
  PriceRange price_range = 2;

  // The type of establishment.
  Text establishment_category = 3;

  // Required. The brand landing pages. At least one must be provided.
  repeated BrandLandingPages brand_landing_pages = 4;
}
```

### BrandLandingPages Definition

```protobuf
// The Localized brand landing pages for a single Point of Interest (POI).
message BrandLandingPages {
  // Required. The brand this configuration applies to.
  string brand_id = 1 [(datapol.semantic_type) = ST_PARTNER_ID];

  // Localized landing page for the Point of Interest (POI).
  message LocalizedLandingPage {

    // The url of the landing page.
    // Max length: 2000.
    string url = 1;

    // Restricts this page to users with the specified language preference.
    // Must contain language tags, such as "en", "en-US" or "sr-Latn".
    // Empty list means this page is not restricted by language.
    repeated string locales = 3;

    // Restricts this page to users from the specified countries.
    // Must contain ISO 3166-1 alpha-2 country codes, e.g. "US".
    // Empty list means this page is not restricted by country.
    // If `is_default_for_country` is true, this field must not be empty.
    repeated string countries = 4;

    // Whether this page should be used as the default fallback for users in
    // `countries` when no entry for that country matches the user's
    // language preference.
    bool is_default_for_country = 5;
  }

  // The localized landing pages.
  // The url and locales fields values must be unique across all the localized
  // landing pages.
  repeated LocalizedLandingPage localized_landing_pages = 2;

  // Required. The default landing page url to be used when none of the
  // localized landing pages matches the user's language.
  string default_url = 3;
}
```

## Samples

### Point of Interest Feed

#### Filename: poi_1707240000.json

```json
{
  "data": [
    {
      "poi_id": "test_restaurant_1",
      "name": {
        "localizations": [
          {
            "locale": "en",
            "text": "Tasty Bites Test Restaurant"
          }
        ],
        "default_locale": "en"
      },
      "telephone": "+1234567890",
      "url": "https://www.tastybitestest.com",
      "location": {
        "latitude": 37.422,
        "longitude": -122.084,
        "address": {
          "country": "US",
          "locality": "Mountain View",
          "postal_code": "94043",
          "street_address": "1600 Amphitheatre Pkwy"
        }
      },
      "display_address": {
        "localizations": [
          {
            "locale": "en",
            "text": "1600 Amphitheatre Pkwy, Mountain View, CA 94043"
          }
        ],
        "default_locale": "en"
      },
      "images": [
        {
          "url": "https://www.tastybitestest.com/images/interior.jpg",
          "alt_text": {
            "localizations": [
              {
                "locale": "en",
                "text": "Cozy dining area of Tasty Bites"
              }
            ],
            "default_locale": "en"
          }
        }
      ],
      "rating": 4.7,
      "num_ratings": 150,
      "rating_scale": 5,
      "category": "LOCAL",
      "description": {
        "localizations": [
          {
            "locale": "en",
            "text": "A mock restaurant for testing the POI feed ingestion."
          }
        ],
        "default_locale": "en"
      },
      "local_data": {
        "establishment_category": {
           "localizations": [
             {
               "locale": "en",
               "text": "Restaurant"
             }
           ],
           "default_locale": "en"
        },
        "price_range": {
          "min_price": {
            "currency_code": "USD",
            "units": 15,
            "nanos": 0
          },
          "max_price": {
            "currency_code": "USD",
            "units": 45,
            "nanos": 0
          }
        },
        "business_hours": {
          "time_ranges": [
            {
              "open_day": "MONDAY",
              "open_time": { "hours": 11, "minutes": 0 },
              "close_day": "MONDAY",
              "close_time": { "hours": 21, "minutes": 0 }
            },
            {
              "open_day": "TUESDAY",
              "open_time": { "hours": 11, "minutes": 0 },
              "close_day": "TUESDAY",
              "close_time": { "hours": 21, "minutes": 0 }
            },
            {
              "open_day": "WEDNESDAY",
              "open_time": { "hours": 11, "minutes": 0 },
              "close_day": "WEDNESDAY",
              "close_time": { "hours": 21, "minutes": 0 }
            },
            {
              "open_day": "THURSDAY",
              "open_time": { "hours": 11, "minutes": 0 },
              "close_day": "THURSDAY",
              "close_time": { "hours": 22, "minutes": 0 }
            },
            {
              "open_day": "FRIDAY",
              "open_time": { "hours": 11, "minutes": 0 },
              "close_day": "FRIDAY",
              "close_time": { "hours": 23, "minutes": 0 }
            },
            {
              "open_day": "SATURDAY",
              "open_time": { "hours": 10, "minutes": 0 },
              "close_day": "SATURDAY",
              "close_time": { "hours": 23, "minutes": 0 }
            },
            {
              "open_day": "SUNDAY",
              "open_time": { "hours": 10, "minutes": 0 },
              "close_day": "SUNDAY",
              "close_time": { "hours": 20, "minutes": 0 }
            }
          ]
        },
        "brand_landing_pages": [
          {
            "brand_id": "tasty_bites_brand",
            "localized_landing_pages": [
              {
                "url": "https://www.tastybitestest.com/en",
                "locales": ["en-US", "en-GB"]
              }
            ],
            "default_url": "https://www.tastybitestest.com"
          }
        ]
      }
    }
  ]
}
```

### Multi-lingual POI Feed

#### Filename: poi_multilingual.json

```json
{
  "data": [
    {
      "poi_id": "test_restaurant_1",
      "name": {
        "localizations": [
          {
            "locale": "en",
            "text": "Tasty Bites Test Restaurant"
          },
          {
            "locale": "fr",
            "text": "Restaurant de test Tasty Bites"
          }
        ],
        "default_locale": "en"
      },
      "telephone": "+1234567890",
      "url": "https://www.tastybitestest.com",
      "location": {
        "latitude": 37.422,
        "longitude": -122.084,
        "address": {
          "country": "US",
          "locality": "Mountain View",
          "postal_code": "94043",
          "street_address": "1600 Amphitheatre Pkwy"
        }
      },
      "display_address": {
        "localizations": [
          {
            "locale": "en",
            "text": "1600 Amphitheatre Pkwy, Mountain View, CA 94043"
          },
          {
            "locale": "fr",
            "text": "1600 Amphitheatre Pkwy, Mountain View, CA 94043"
          }
        ],
        "default_locale": "en"
      },
      "images": [
        {
          "url": "https://www.tastybitestest.com/images/interior.jpg",
          "alt_text": {
            "localizations": [
              {
                "locale": "en",
                "text": "Cozy dining area of Tasty Bites"
              },
              {
                "locale": "fr",
                "text": "Espace salle à manger accueillant de Tasty Bites"
              }
            ],
            "default_locale": "en"
          }
        }
      ],
      "rating": 4.7,
      "num_ratings": 150,
      "rating_scale": 5,
      "category": "LOCAL",
      "description": {
        "localizations": [
          {
            "locale": "en",
            "text": "A mock restaurant for testing the POI feed ingestion."
          },
          {
            "locale": "fr",
            "text": "Un faux restaurant pour tester l'ingestion de flux de points d'intérêt."
          }
        ],
        "default_locale": "en"
      },
      "local_data": {
        "establishment_category": {
           "localizations": [
             {
               "locale": "en",
               "text": "Restaurant"
             },
             {
               "locale": "fr",
               "text": "Restaurant"
             }
           ],
           "default_locale": "en"
        },
        "price_range": {
          "min_price": {
            "currency_code": "USD",
            "units": 15,
            "nanos": 0
          },
          "max_price": {
            "currency_code": "USD",
            "units": 45,
            "nanos": 0
          }
        },
        "business_hours": {
          "time_ranges": [
            {
              "open_day": "MONDAY",
              "open_time": { "hours": 11, "minutes": 0 },
              "close_day": "MONDAY",
              "close_time": { "hours": 21, "minutes": 0 }
            },
            {
              "open_day": "TUESDAY",
              "open_time": { "hours": 11, "minutes": 0 },
              "close_day": "TUESDAY",
              "close_time": { "hours": 21, "minutes": 0 }
            },
            {
              "open_day": "WEDNESDAY",
              "open_time": { "hours": 11, "minutes": 0 },
              "close_day": "WEDNESDAY",
              "close_time": { "hours": 21, "minutes": 0 }
            },
            {
              "open_day": "THURSDAY",
              "open_time": { "hours": 11, "minutes": 0 },
              "close_day": "THURSDAY",
              "close_time": { "hours": 22, "minutes": 0 }
            },
            {
              "open_day": "FRIDAY",
              "open_time": { "hours": 11, "minutes": 0 },
              "close_day": "FRIDAY",
              "close_time": { "hours": 23, "minutes": 0 }
            },
            {
              "open_day": "SATURDAY",
              "open_time": { "hours": 10, "minutes": 0 },
              "close_day": "SATURDAY",
              "close_time": { "hours": 23, "minutes": 0 }
            },
            {
              "open_day": "SUNDAY",
              "open_time": { "hours": 10, "minutes": 0 },
              "close_day": "SUNDAY",
              "close_time": { "hours": 20, "minutes": 0 }
            }
          ]
        },
        "brand_landing_pages": [
          {
            "brand_id": "tasty_bites_brand",
            "localized_landing_pages": [
              {
                "url": "https://www.tastybitestest.com/fr",
                "locales": ["fr-FR", "fr-CA"]
              },
              {
                "url": "https://www.tastybitestest.com/en",
                "locales": ["en-US", "en-GB"]
              }
            ],
            "default_url": "https://www.tastybitestest.com"
          }
        ]
      }
    }
  ]
}
```