/api/v4/locationsCrear una ubicación
Crea una nueva ubicación de negocio en tu cuenta y la pone en cola para el envío de fichas.
Parámetros
Cuerpo
Un campo anidado marcado como obligatorio solo se aplica cuando envías su campo principal. Si el campo principal es opcional y lo omites, sus campos hijos obligatorios no se aplican.
| Nombre | Tipo | Obligatorio | Descripción |
|---|---|---|---|
| input.name | string | obligatorio | Name of the business. |
| input.description | string | obligatorio | Business description, minimum 200 characters (`SY10005` when missing or shorter). Publishers use it as the primary listing copy. |
| input.storeId | string | opcional | Unique store code. Must be unique across the account. |
| input.street | string | obligatorio | Street address, 5 to 100 characters (`SY10011`). |
| input.city | string | obligatorio | City. Required where the country's `hasCity` is `true` (`SY10126`). Where it is `false`, a city you send is dropped. |
| input.stateIso | string | obligatorio | State ISO code. Required where the country's `stateRequired` is `true`, and must be one of that country's `states` (`SY10010`). Leave it out where `stateRequired` is `false`. See the countries and states endpoint for valid values. |
| input.postalCode | string | opcional | Postal code. Optional, but send it wherever the country's `hasPostalCode` is `true`. A value you send must match the country's format (`SY10014`). |
| input.countryIso | string | obligatorio | Country ISO code. Must be a supported country (`SY10036`). See the countries and states endpoint for valid values. |
| input.phone | string | obligatorio | Primary phone number, validated for the country (`SY10015`). |
| input.subCategoryId | integer | obligatorio | Primary subcategory ID. Pick a valid ID from the subcategories list endpoint. |
| input.bizUrl | string | obligatorio | Business website URL. Published to directories as the location's website. Some publishers refuse a listing without one. |
| input.primaryGbpSiteCategoryId | string | opcional | Primary Google Business Profile category, as a GCID (e.g. `gcid:restaurant`). Resolved against `countryIso`, so send the two together. |
| input.additionalGbpSiteCategoryIds | array of strings | opcional | Additional Google Business Profile categories, as GCIDs. Also resolved against `countryIso`. |
| input.offeringsUrl | string | opcional | URL of the menu, catalogue, or service list. |
| input.bookingUrl | string | opcional | URL customers use to book an appointment. |
| input.reservationUrl | string | opcional | URL customers use to make a reservation. |
| input.street1 | string | opcional | Second address line (suite, unit, floor). |
| input.latitude | string | opcional | Latitude of the location, as a string. Send with `longitude`; publishers use it when the address alone is ambiguous. |
| input.longitude | string | opcional | Longitude of the location, as a string. Send with `latitude`. |
| input.ownerEmail | string | opcional | Email of the location owner. Used for listing claims and verification, not for login. |
| input.ownerName | string | opcional | Name of the location owner. |
| input.facebookUrl | string | opcional | URL of the location's Facebook page. |
| input.twitterUrl | string | opcional | URL of the location's X (Twitter) profile. |
| input.linkedinUrl | string | opcional | URL of the location's LinkedIn page. |
| input.instagramUrl | string | opcional | URL of the location's Instagram profile. |
| input.youtubeUrl | string | opcional | URL of the location's YouTube channel. |
| input.tiktokUrl | string | opcional | URL of the location's TikTok profile. |
| input.pinterestUrl | string | opcional | URL of the location's Pinterest profile. |
| input.tagline | string | opcional | Short tagline for the business. |
| input.yearOfIncorporation | string | opcional | Year the business was incorporated, e.g. `2014`. |
| input.googleAdsPhone | string | opcional | Alternate phone shown on Google Ads location extensions instead of `phone`. |
| input.additionalPhones | array of strings | opcional | Secondary phone numbers submitted to Google Business Profile. |
| input.videos | array of strings | opcional | Video URLs for the location. |
| input.additionalCategoryIds | array of integers | opcional | Secondary Listings API subcategory IDs, from the subcategories endpoint. Distinct from `additionalGbpSiteCategoryIds`, which takes Google GCIDs. |
| input.submissionDisabledSiteIds | array of integers | opcional | Site IDs to exclude from submission. The inverse of `enabledSiteIds`, useful when you want every site in your plan except a few. |
| input.hideAddress | boolean | opcional | Set `true` for a service-area business. ListingsAPI stores the address you send but does not submit it to publishers. |
| input.temporarilyClosed | boolean | opcional | Set `true` to stop publishing business hours while the location is temporarily closed. |
| input.serviceItems | array of objects | opcional | Services offered, published to Google Business Profile. |
| input.customAttributes | array of objects | opcional | Publisher-specific attributes for the location. |
| input.paymentMethods | array of strings | opcional | Payment methods accepted. One or more of `VISA`, `MASTERCARD`, `AMEX`, `CASH`, `CHEQUE`, `CRYPTO`, `DINERS_CLUB`, `DISCOVER`, `FINANCING`, `INVOICE`, `TRAVELERS_CHECK`, `APPLE_PAY`, `SAMSUNG_PAY`, `PAYPAL`, `ANDROID_PAY`. |
| input.businessHours | array of objects | opcional | Opening hours. Each entry is `{ day, type, slots }`, plus `specialDate` for a `SPECIAL` entry: `day` is an uppercase weekday enum (MONDAY–SUNDAY) or `SPECIAL`, `type` is `OPEN` or `CLOSED`, and `slots` is an array of `{ start, end }` time strings (e.g. `09:00am`, `05:00pm`). For a closed day use `type: "CLOSED"` with an empty `slots` array. |
| input.businessHours[].day | string | obligatorio | MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY, or SPECIAL (a one-off override for the date in `specialDate`). |
| input.businessHours[].type | string | obligatorio | `OPEN` or `CLOSED`. |
| input.businessHours[].specialDate | string | opcional | Date of a one-off override, as `YYYY-MM-DD`. Set this only when `day` is `SPECIAL`. |
| input.businessHours[].slots | array of objects | opcional | Open intervals for the day, each `{ start, end }`. Omit or leave empty when `type` is `CLOSED`. |
| input.businessHours[].slots[].start | string | obligatorio | Opening time, e.g. `09:00am`. |
| input.businessHours[].slots[].end | string | obligatorio | Closing time, e.g. `05:00pm`. |
| input.serviceArea | object | opcional | Service-area definition for service-area businesses: `{ businessType, regionCode, placeInfos: [{ placeId, placeName }] }`. |
| input.placeActionLinks | array of objects | opcional | Google action links (ordering, delivery, takeout, reservation, appointment). Each item: `placeActionType` (enum), `uri` (string), optional `isPreferred` (boolean). On create every link is new, so no `action` is needed. See the Place Action Links guide. |
| input.enabledSiteIds | array of integers | opcional | Site IDs to publish this location to, when you want a subset of your plan's sites. See the plan-sites endpoint for valid IDs. Omit to publish to every site in your plan. |
| input.clientMutationId | string | opcional | Optional correlation token returned unchanged in the response. It does not prevent duplicate writes: the server does not detect repeated calls that reuse the same value. |
Solicitud de ejemplo
Cuerpo listo para pegar. Sustituye los ID y valores de ejemplo por los tuyos.
{ "input": { "name": "Acme Kitchen", "description": "Acme Kitchen is a family-owned neighborhood restaurant in downtown New York serving wood-fired pizza, hand-rolled pasta, and a short seasonal menu built around produce from nearby growers. Our dining room seats forty, takeout and delivery run until close, and the bar pours regional wine and beer on tap.", "storeId": "ACME01", "street": "123 Jump Street", "city": "New York", "stateIso": "NY", "postalCode": "10013", "countryIso": "US", "phone": "6443859313", "bizUrl": "https://acmekitchen.example.com", "subCategoryId": 1432, "primaryGbpSiteCategoryId": "gcid:restaurant", "additionalGbpSiteCategoryIds": ["gcid:pizza_restaurant"], "businessHours": [ { "day": "MONDAY", "type": "OPEN", "slots": [{ "start": "09:00am", "end": "05:00pm" }] }, { "day": "TUESDAY", "type": "OPEN", "slots": [{ "start": "09:00am", "end": "05:00pm" }] }, { "day": "WEDNESDAY", "type": "OPEN", "slots": [{ "start": "09:00am", "end": "05:00pm" }] }, { "day": "THURSDAY", "type": "OPEN", "slots": [{ "start": "09:00am", "end": "05:00pm" }] }, { "day": "FRIDAY", "type": "OPEN", "slots": [{ "start": "09:00am", "end": "05:00pm" }] }, { "day": "SATURDAY", "type": "OPEN", "slots": [{ "start": "10:00am", "end": "02:00pm" }] }, { "day": "SUNDAY", "type": "CLOSED", "slots": [] } ], "placeActionLinks": [ { "placeActionType": "FOOD_ORDERING", "uri": "https://order.acmekitchen.example.com", "isPreferred": true }, { "placeActionType": "FOOD_TAKEOUT", "uri": "https://takeout.acmekitchen.example.com" } ] }}Respuestas
200Location created successfully. Returns the new location as a summary object.
{ "data": { "createLocation": { "clientMutationId": null, "success": true, "errors": null, "location": { "id": "TG9jYXRpb246MTgwMDI5MA==", "databaseId": 1800290, "storeId": "ACME01", "name": "Acme Kitchen", "street": "123 Jump Street", "city": "New York", "stateIso": "NY", "postalCode": "10013", "countryIso": "US", "phone": "6443859313", "status": "PENDING", "primaryGbpSiteCategoryId": null, "placeActionLinks": [ { "placeActionType": "FOOD_ORDERING", "uri": "https://order.acmekitchen.example.com", "isPreferred": true, "name": null, "submissionStatus": null }, { "placeActionType": "FOOD_TAKEOUT", "uri": "https://takeout.acmekitchen.example.com", "isPreferred": false, "name": null, "submissionStatus": null } ], "discoveredPlaceActionLinks": [] } } }}400Bad request, validation failure (see `errors[]`).
401Unauthenticated, missing or invalid API key.
429Rate limit exceeded. Retry after the `Retry-After` header value.
Crea una nueva ubicación de negocio. Si la operación se completa correctamente, la ubicación se pone en cola para su envío a todas las plataformas de publicación de su plan (o, si se proporciona enabledSiteIds, solo a esos sitios). Campos obligatorios: name, un description de al menos 200 caracteres, subCategoryId, countryIso y, en los países cuyo sistema de direcciones requiere una ciudad, city. Una ubicación también necesita una dirección postal y un teléfono válidos para poder publicarse; proporciónalos al crearla para evitar una actualización posterior.
El id devuelto está codificado en base64 (e.g. TG9jYXRpb246MTgwMDI5MA==); decodifícalo para obtener la forma interna Location:<databaseId>. Todas las llamadas posteriores hacen referencia a este id en base64.
Caso de uso: dar de alta un único establecimiento con horario. Envía la dirección, phone, subCategoryId y un array businessHours, con una entrada por cada día de la semana que incluya franjas type: "OPEN" y { start, end }, o type: "CLOSED" con un array slots vacío para los días de cierre. Guarda tu propia clave en storeId para poder localizar la ubicación más adelante mediante obtener por códigos de tienda sin tener que guardar el ID de Listings API.
Los horarios especiales requieren un horario habitual. Los horarios especiales (excepciones por festivos o eventos, enviados como entradas businessHours con day: "SPECIAL", type: "OPEN" o "CLOSED", y un specialDate en formato YYYY-MM-DD) solo se publican cuando la ubicación también incluye su horario habitual de MONDAY a SUNDAY; Google rechaza una ubicación enviada con horarios especiales pero sin horario habitual. Incluye siempre los siete días de la semana en businessHours cuando establezcas entradas SPECIAL; consulta las reglas de horarios del endpoint de actualización para conocer el modelo completo.
Caso de uso: publicar en un subconjunto de sitios. Pasa enabledSiteIds (los ID de sitios del endpoint plan-sites) para publicar la ubicación en un subconjunto seleccionado de directorios en lugar de en todos los del plan; este es el patrón que utilizan las agencias para vender cobertura de sitios por niveles.
Configura los botones de acción de Google al crear la ubicación. Pasa placeActionLinks para configurar los botones de acción de Google de la ubicación (reservar una cita, hacer un pedido en línea, etc.) en la misma llamada. Los valores válidos de placeActionType son APPOINTMENT, ONLINE_APPOINTMENT, DINING_RESERVATION, FOOD_ORDERING, FOOD_DELIVERY, FOOD_TAKEOUT y SHOP_ONLINE, con un máximo de un enlace preferido por tipo. Inmediatamente después de la creación, name y submissionStatus de cada enlace tienen el valor null hasta que el enlace se sincroniza con Google. Para añadir, editar o eliminar enlaces más adelante, utiliza actualizar una ubicación; consulta la guía de Place Action Links para conocer el modelo completo.
Errores comunes (devueltos como 400 con detalles en errors[]): description debe tener al menos 200 caracteres (SY10005), countryIso debe ser un país admitido (SY10036), city es obligatorio en los países cuyo sistema de direcciones requiere una ciudad (SY10126), state debe ser un código ISO válido, el código postal y el teléfono deben ser válidos para el país, subCategoryId debe existir y storeId debe ser único en toda la cuenta. Todas las solicitudes consumen lo mismo de tu límite de solicitudes independientemente del endpoint, por lo que dar de alta un gran volumen de ubicaciones provoca un 429 solo por el número de solicitudes; respeta la cabecera Retry-After y crea las ubicaciones de forma secuencial en lugar de hacerlo en una ráfaga.
curl -X POST 'https://listingsapi.com/api/v4/locations' \ -H "Authorization: API $LISTINGSAPI_KEY" \ -H 'Content-Type: application/json' \ -d '{ "input": { "name": "Acme Kitchen", "description": "Acme Kitchen is a family-owned neighborhood restaurant in downtown New York serving wood-fired pizza, hand-rolled pasta, and a short seasonal menu built around produce from nearby growers. Our dining room seats forty, takeout and delivery run until close, and the bar pours regional wine and beer on tap.", "storeId": "ACME01", "street": "123 Jump Street", "city": "New York", "stateIso": "NY", "postalCode": "10013", "countryIso": "US", "phone": "6443859313", "bizUrl": "https://acmekitchen.example.com", "subCategoryId": 1432, "primaryGbpSiteCategoryId": "gcid:restaurant", "additionalGbpSiteCategoryIds": [ "gcid:pizza_restaurant" ], "businessHours": [ { "day": "MONDAY", "type": "OPEN", "slots": [ { "start": "09:00am", "end": "05:00pm" } ] }, { "day": "TUESDAY", "type": "OPEN", "slots": [ { "start": "09:00am", "end": "05:00pm" } ] }, { "day": "WEDNESDAY", "type": "OPEN", "slots": [ { "start": "09:00am", "end": "05:00pm" } ] }, { "day": "THURSDAY", "type": "OPEN", "slots": [ { "start": "09:00am", "end": "05:00pm" } ] }, { "day": "FRIDAY", "type": "OPEN", "slots": [ { "start": "09:00am", "end": "05:00pm" } ] }, { "day": "SATURDAY", "type": "OPEN", "slots": [ { "start": "10:00am", "end": "02:00pm" } ] }, { "day": "SUNDAY", "type": "CLOSED", "slots": [] } ], "placeActionLinks": [ { "placeActionType": "FOOD_ORDERING", "uri": "https://order.acmekitchen.example.com", "isPreferred": true }, { "placeActionType": "FOOD_TAKEOUT", "uri": "https://takeout.acmekitchen.example.com" } ] } }'