Crea e carica i feed dei PDI
Quando crei e carichi i feed dei PDI, segui queste istruzioni:
- Segui le specifiche descritte nel feed dei PDI per i file di dati dei PDI. Ti consigliamo di utilizzare nomi file dei dati dei PDI univoci per ogni caricamento. Includi un timestamp nel nome file, ad esempio
POI_1633621547.json. - Carica i feed sul server SFTP locale dei PDI ogni giorno come aggiornamenti completi.
- Puoi trovare i dettagli del server SFTP nella sezione Configurazione > Feed del Partner Portal.
- Convalida il feed dei PDI prima di caricarlo utilizzando lo POI Feed Validator.
- Visualizza lo stato di importazione del feed nella sezione Importazione > Cronologia del Partner Portal.
Linee guida per i pacchetti di file
Per garantire un'importazione corretta, rispetta i seguenti requisiti di pacchettizzazione:
- Archivio JSON aggregato singolo (obbligatorio): combina tutti i record delle entità in un unico file JSON. Ti consigliamo di comprimerlo in un unico archivio GZIP e di caricarlo.
- Avviso relativo agli anti-pattern: non utilizzare un file per entità o più file separati per paese nello stesso archivio. Questo approccio non è supportato e causerà errori di estrazione.
Supporto multilingue
Il feed dei punti di interesse supporta la fornitura di contenuti localizzati per campi specifici. I seguenti campi sono di tipo Text e supportano la localizzazione:
namedescriptiondisplay_address
Per fornire contenuti in più lingue, devi specificare un default_locale nel campo e fornire le stringhe localizzate nell'elenco localizations.
Fornisci tutte le localizzazioni per un'entità in una singola voce del PDI. Non suddividere una singola entità in più file JSON di lingue diverse.
Esempio:
"name": {
"localizations": [
{
"locale": "en",
"text": "Tasty Bites Test Restaurant"
},
{
"locale": "es",
"text": "Restaurante de prueba Tasty Bites"
}
],
"default_locale": "en"
}
Linee guida per le immagini
- Formato: deve essere JPEG, PNG o WebP.
- Dimensione massima del file: inferiore a 30 MB per immagine.
- Dimensioni massime: meno di 75 megapixel totali (larghezza x altezza < 75.000.000).
- Tipo di URL: percorso diretto all'asset immagine (ad es. termina con .jpg).
- Autorizzazioni: assicurati che il server di hosting consenta l'accesso a Googlebot o ai crawler e che non abbia un file robots.txt che blocca le directory delle immagini.
- Ricerca sicura: le immagini devono rispettare le norme relative alla ricerca sicura di Google.
Specifiche dei feed
Requisiti dei campi
VssPoi
Rappresenta una singola entità di punto d'interesse (PDI), ad esempio un hotel o un ristorante.
| Nome campo | Tipo | Requisito | Descrizione |
|---|---|---|---|
poi_id | stringa | Obbligatorio | Obbligatorio. Una stringa generata dal partner che identifica un PDI. |
name | object(Text) | Obbligatorio | Obbligatorio. Il nome del PDI. |
telephone | stringa | Il numero di telefono di contatto del PDI, inclusi i prefissi paese e area, ad esempio +14567891234. | |
url | stringa | L'URL del sito web pubblico del PDI. Nota: questo verrà utilizzato solo per la corrispondenza, non per la visualizzazione. | |
location | object(GeoCoordinates) | Obbligatorio | Obbligatorio. La posizione del PDI. |
display_address | object(Text) | L'indirizzo visualizzato nell'interfaccia utente. | |
images | array di oggetti(Image) | Immagini del PDI. Numero massimo di immagini: 5. | |
rating | numero | Valutazione media del PDI. | |
num_ratings | numero | Il numero di valutazioni che contribuiscono al campo rating. | |
rating_scale | numero | La scala di valutazione utilizzata per il campo rating. Se la valutazione massima è 5, rating_scale è 5. | |
category | enum(Category) | Obbligatorio | Obbligatorio. Rappresenta la categoria del PDI. |
description | object(Text) | Una descrizione del PDI. | |
| oneOf(additional_data) | Obbligatorio | È possibile impostare un solo campo in questo oneOf. |
Testo
Rappresenta un testo con localizzazioni.
| Nome campo | Tipo | Requisito | Descrizione |
|---|---|---|---|
localizations | array di oggetti(LocalizedString) | Le stringhe localizzate. | |
default_locale | stringa | Le impostazioni internazionali da utilizzare come lingua predefinita devono essere presenti nelle localizzazioni. |
LocalizedString
Rappresenta una stringa localizzata.
| Nome campo | Tipo | Requisito | Descrizione |
|---|---|---|---|
locale | stringa | Il tag lingua del testo, ad esempio "en", "en-US" o "sr-Latn". | |
text | stringa | Il testo nella lingua specificata. |
GeoCoordinates
I dati geografici di una località, tra cui latitudine, longitudine e indirizzo.
| Nome campo | Tipo | Requisito | Descrizione |
|---|---|---|---|
latitude | numero | [-90, +90] gradi (inclusi). Obbligatorio se è impostata la longitudine, altrimenti facoltativo. | |
longitude | numero | [-180, +180] gradi (inclusi). Obbligatorio se è impostata la latitudine, altrimenti facoltativo. | |
| oneOf(addresses) | Obbligatorio | È possibile impostare un solo campo in questo oneOf. |
PostalAddress
L'indirizzo postale della sede.
| Nome campo | Tipo | Requisito | Descrizione |
|---|---|---|---|
country | stringa | Obbligatorio | Obbligatorio. Il paese, utilizzando il codice paese ISO 3166-1 alpha-2, ad esempio "US". |
locality | stringa | Obbligatorio | Obbligatorio. La località/città, ad esempio "Mountain View". |
region | stringa | La regione/lo stato/la provincia, ad esempio "CA". Questo campo è obbligatorio solo nei paesi in cui la regione fa comunemente parte dell'indirizzo. (facoltativo) | |
postal_code | stringa | Obbligatorio | Obbligatorio. Il codice postale, ad esempio "94043". |
street_address | stringa | Obbligatorio | Obbligatorio. La via, ad esempio "1600 Amphitheatre Pkwy". |
Immagine
Rappresenta un'immagine del punto d'interesse (PDI).
| Nome campo | Tipo | Requisito | Descrizione |
|---|---|---|---|
url | stringa | L'URL dell'immagine. Google eseguirà la scansione dei contenuti multimediali ospitati in questo URL. Lunghezza massima: 2000. | |
alt_text | object(Text) | Il testo alternativo da utilizzare per l'accessibilità. |
HotelData
Dati del feed specifici per l'hotel.
| Nome campo | Tipo | Requisito | Descrizione |
|---|---|---|---|
hotel_star_class | numero | Il valore in stelle della categoria hotel ufficiale. Può essere utilizzato in un'etichetta come "hotel a 5 stelle". Questo valore deve essere un numero intero compreso tra 0 e 5. Se una valutazione non è disponibile o non è specificata, deve essere utilizzata una valutazione pari a 0. Se impostato su 0, non verrà visualizzata alcuna classe di stelle nell'interfaccia utente per gli utenti. | |
brand_ids | array di stringhe | I brand che possono mostrare questo hotel. Se questo campo è vuoto, l'hotel può essere visualizzato con uno qualsiasi dei brand associati al feed. |
LocalData
Dati del feed specifici per l'attività.
| Nome campo | Tipo | Requisito | Descrizione |
|---|---|---|---|
business_hours | object(BusinessHours) | L'orario di apertura normale dell'attività. | |
price_range | object(PriceRange) | Fascia di prezzo dei servizi offerti dall'attività. | |
establishment_category | object(Text) | Il tipo di struttura. | |
brand_landing_pages | array di oggetti(BrandLandingPages) | Obbligatorio | Obbligatorio. Le pagine di destinazione del brand. Devi specificarne almeno uno. |
BusinessHours
Rappresenta i periodi di tempo in cui questa sede è aperta. Contiene una raccolta di istanze [TimeRange][madden.vss_poi_feed.TimeRange]. Esempio: aperto il sabato dalle 09:00 alle 12:00 e dalle 13:00 alle 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 } } Esempio: aperto il sabato dalle 21:00 alle 02:00 della domenica: time_ranges { open_day: SATURDAY open_time: { hours: 21, minutes: 0 } close_day: SUNDAY close_time: { hours: 2, minutes: 0 } }
| Nome campo | Tipo | Requisito | Descrizione |
|---|---|---|---|
time_ranges | array di oggetti(TimeRange) | Una raccolta di orari in cui questo PDI è aperto. Ogni periodo rappresenta un intervallo di ore in cui il POI è aperto durante la settimana. |
TimeRange
Rappresenta un periodo di tempo in cui il POI è aperto, a partire dal giorno/ora di apertura specificato fino al giorno/ora di chiusura specificato. L'orario di chiusura deve essere successivo all'orario di apertura, ad esempio più tardi nello stesso giorno o in un giorno successivo.
| Nome campo | Tipo | Requisito | Descrizione |
|---|---|---|---|
open_day | enum(DayOfWeek) | Il giorno di apertura dell'intervallo di tempo. | |
open_time | object(TimeOfDay) | L'orario di apertura dell'intervallo di tempo. | |
close_day | enum(DayOfWeek) | Il giorno di chiusura dell'intervallo di tempo. | |
close_time | object(TimeOfDay) | L'ora di fine dell'intervallo di tempo. |
TimeOfDay
| Nome campo | Tipo | Requisito | Descrizione |
|---|---|---|---|
hours | numero | Ore di un giorno nel formato 24 ore. Deve essere maggiore o uguale a 0 e in genere deve essere minore o uguale a 23. Un'API può scegliere di consentire il valore "24:00:00" per scenari come l'orario di chiusura di un'attività. | |
minutes | numero | Minuti di un'ora. Deve essere maggiore o uguale a 0 e minore o uguale a 59. | |
seconds | numero | Secondi di un minuto. Deve essere maggiore o uguale a 0 e in genere deve essere minore o uguale a 59. Un'API può consentire il valore 60 se consente i secondi intercalari. | |
nanos | numero | Frazioni di secondi, in nanosecondi. Deve essere maggiore o uguale a 0 e minore o uguale a 999.999.999. |
PriceRange
Fascia di prezzo dei servizi offerti dal PDI.
| Nome campo | Tipo | Requisito | Descrizione |
|---|---|---|---|
min_price | object(Money) | Il prezzo minimo dei servizi offerti dal POI. | |
max_price | object(Money) | Il prezzo massimo dei servizi offerti dal PDI. |
Denaro
Rappresenta un importo di denaro con il relativo tipo di valuta.
| Nome campo | Tipo | Requisito | Descrizione |
|---|---|---|---|
currency_code | stringa | Il codice valuta di tre lettere definito nello standard ISO 4217. | |
units | numero | Le unità intere dell'importo.
Ad esempio, se currencyCode è "USD", 1 unità corrisponde a un dollaro statunitense. | |
nanos | numero | Numero di unità nano (10^-9) dell'importo.
Il valore deve essere compreso tra -999.999.999 e +999.999.999 inclusi.
Se units è positivo, nanos deve essere positivo o zero.
Se units è zero, nanos può essere positivo, zero o negativo.
Se units è negativo, nanos deve essere negativo o uguale a zero.
Ad esempio, -1,75 $ è rappresentato come units=-1 e nanos=-750.000.000. |
BrandLandingPages
Le pagine di destinazione del brand localizzate per un singolo punto d'interesse (PDI).
| Nome campo | Tipo | Requisito | Descrizione |
|---|---|---|---|
brand_id | stringa | Obbligatorio | Obbligatorio. Il brand a cui si applica questa configurazione. |
localized_landing_pages | array di oggetti(LocalizedLandingPage) | Le pagine di destinazione localizzate. I valori dei campi url e locales devono essere univoci in tutte le pagine di destinazione localizzate. | |
default_url | stringa | Obbligatorio | Obbligatorio. L'URL pagina di destinazione predefinito da utilizzare quando nessuna delle pagine di destinazione localizzate corrisponde alla lingua dell'utente. |
LocalizedLandingPage
Pagina di destinazione localizzata per il punto d'interesse (PDI).
| Nome campo | Tipo | Requisito | Descrizione |
|---|---|---|---|
url | stringa | L'URL della pagina di destinazione. Lunghezza massima: 2000. | |
locales | array di stringhe | Limita questa pagina agli utenti con le preferenze sulla lingua specificate. Deve contenere tag lingua, ad esempio "en", "en-US" o "sr-Latn". |
Categoria
Rappresenta la categoria del PDI.
Deve corrispondere al campo oneof additional_data di seguito.
| Nome | Descrizione |
|---|---|
UNKNOWN_CATEGORY | |
HOTEL | |
LOCAL |
DayOfWeek
Rappresenta un giorno della settimana.
| Nome | Descrizione |
|---|---|
DAY_OF_WEEK_UNSPECIFIED | Il giorno della settimana non è specificato. |
MONDAY | Lunedì |
TUESDAY | Martedì |
WEDNESDAY | Mercoledì |
THURSDAY | Giovedì |
FRIDAY | Venerdì |
SATURDAY | Sabato |
SUNDAY | Domenica |
additional_data
Obbligatorio. Campi specifici per categoria.
Deve corrispondere al campo category sopra.
| Nome campo | Tipo | Requisito | Descrizione |
|---|---|---|---|
hotel_data | object(HotelData) | Si esclude a vicenda con | Campi specifici dell'hotel. |
local_data | object(LocalData) | Si esclude a vicenda con | Campi specifici per la località. |
indirizzi
Obbligatorio. Indirizzo di una località.
| Nome campo | Tipo | Requisito | Descrizione |
|---|---|---|---|
address | object(PostalAddress) | Indirizzo postale della località. |
Definizioni
Definizione di VssPoiFeed
// Represents a Point of Interest (POI) data feed provided by a partner. export message VssPoiFeed { // The POIs in the feed. repeated VssPoi data = 1; }
Definizione di VssPoi
// 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; } }
Definizione del testo
// 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; }
Definizione di GeoCoordinates
// 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; } }
Definizione di PostalAddress
// 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; }
Definizione dell'immagine
// 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; }
Definizione di LocalData
// 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; }
Definizione di BrandLandingPages
// 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; }
Esempi
Feed dei punti d'interesse
Nome file: poi_1707240000.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" } ] } } ] }
Feed dei PDI multilingue
Nome file: poi_multilingual.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" } ] } } ] }