Locais

Endpoints de locais com cURL, Python e Node, em ordem de uso: listar, buscar, consultar por ID/código da loja, criar, atualizar, arquivar e fotos.

Listagens, avaliações, publicações e análises são vinculadas a um ID de local. O recurso Locations tem treze endpoints: quatro de leitura para encontrar locais, quatro de escrita para criá-los, alterá-los e arquivá-los, e cinco para gerenciar fotos. Uma chave Read (leitura) permite as operações de leitura. Cada POST exige uma chave Write (escrita); ao usar uma chave Read em uma operação de escrita, o endpoint retorna HTTP 400 com SY90016.

Cada id neste guia é o id Relay em base64, por exemplo, TG9jYXRpb246MTgwMDI4OQ== (que, decodificado, resulta em Location:1800289). Ambos os SDKs também aceitam o databaseId numérico e o codificam para você.

Visão geral dos endpoints

MétodoCaminhoO que fazReferência
GET/locationsPercorre todos os locais com paginação, dos mais recentes para os mais antigos.Listar todos os locais
GET/locations/searchEncontra locais por palavra-chave no nome, endereço e id da loja.Pesquisar locais
GET/locations-by-idsObtém os registros completos correspondentes a um lote de ids em base64.Obter locais por IDs
GET/locations-by-store-codesObtém os registros completos correspondentes aos seus próprios códigos de loja.Obter locais por códigos de loja
POST/locationsCria um local e o coloca na fila para envio.Criar um local
POST/locations/updateAltera qualquer campo que permita escrita em um local.Atualizar um local
POST/locations/archiveAgenda o arquivamento de locais para o fim do ciclo de cobrança.Arquivar locais
POST/locations/cancel_archiveRetorna ao estado ativo os locais com arquivamento agendado.Cancelar arquivamento agendado
POST/locations/photosAnexa um logotipo, uma capa ou fotos da galeria por URL.Enviar fotos
GET/locations/photos/requests/{requestId}Consulta periodicamente um envio em massa que está na fila.Verificar o status do envio em massa
GET/locations/{locationId}/photosLista todos os arquivos de mídia de um local.Obter fotos
POST/locations/photos/starMarca ou desmarca fotos adicionais com uma estrela.Marcar fotos com estrela
POST/locations/photos/removeDesvincula fotos adicionais.Remover fotos

Listar todos os locais

GET /locations percorre todos os locais da conta com paginação, dos mais recentes para os mais antigos. É uma conexão baseada em cursor: edges[].node contém cada registro, e pageInfo.endCursor fornece o valor do parâmetro after para a próxima página. Use esse endpoint para sincronizar toda a conta com o seu próprio sistema.

Parâmetros

NomeEmObrigatórioObservações
firstqueryNãoTamanho da página ao avançar. O padrão é 50. Combine com after.
afterqueryNãoO pageInfo.endCursor da página anterior.
lastqueryNãoTamanho da página ao retroceder. Combine com before.
beforequeryNãoO cursor da primeira aresta da página a partir da qual você está retrocedendo. pageInfo não tem startCursor.
filterqueryNãoObjeto codificado em JSON para restringir o conjunto no servidor, por exemplo, por status de aprovação. O método de listagem de nenhum dos SDKs aceita esse objeto; faça uma chamada REST para obter um subconjunto filtrado.
List
curl "https://listingsapi.com/api/v4/locations?first=50" \-H "Authorization: API $LISTINGSAPI_KEY"
JSON
{  "data": {    "allLocations": {      "edges": [        {          "cursor": "TG9jYXRpb246MTgwMDI4OQ==",          "node": {            "id": "TG9jYXRpb246MTgwMDI4OQ==",            "databaseId": 1800289,            "name": "Jenny Home",            "storeId": null,            "approved": "APPROVED",            "archived": false,            "archivalScheduledAt": null,            "city": "Austin",            "stateIso": "TX",            "countryIso": "US",            "subCategoryId": 1432,            "planName": "Launch",            "placeActionLinks": [],            "discoveredPlaceActionLinks": []          }        }      ],      "pageInfo": {        "hasNextPage": false,        "hasPreviousPage": false,        "endCursor": "TG9jYXRpb246MTgwMDI4OQ==",        "total": 1      }    }  }}

Leia pageInfo.hasNextPage e pare quando o valor for false. A contagem no nível da página é pageInfo.total. O id do nó é o identificador esperado por todos os outros endpoints.

Pesquisar locais

GET /locations/search busca correspondências de uma palavra-chave no nome do local, endereço, cidade e id da loja. É uma conexão baseada em cursor com a mesma estrutura de edges[].node e pageInfo.endCursor usada na listagem. Use esse endpoint em um seletor com sugestões durante a digitação ou para confirmar que uma loja existe antes de criá-la.

Parâmetros

NomeEmObrigatórioObservações
queryqueryNãoA palavra-chave da pesquisa. Omita para percorrer todos os locais com paginação, sem filtros.
firstqueryNãoTamanho da página. O padrão é 50.
afterqueryNãoO pageInfo.endCursor da página anterior.
filterqueryNãoObjeto de filtro codificado em JSON, como no endpoint de listagem.

Ambos os SDKs também aceitam uma lista fields para restringir a busca por correspondências a campos específicos, por exemplo, apenas name.

Search
curl "https://listingsapi.com/api/v4/locations/search?query=Jenny&first=10" \-H "Authorization: API $LISTINGSAPI_KEY"
JSON
{  "data": {    "searchLocations": {      "edges": [        {          "cursor": "TG9jYXRpb246MTgwMDI4OQ==",          "node": {            "id": "TG9jYXRpb246MTgwMDI4OQ==",            "databaseId": 1800289,            "name": "Jenny Home",            "storeId": null,            "street": "600 Congress Ave, Suite 200",            "city": "Austin",            "approved": "APPROVED",            "archived": false          }        }      ],      "pageInfo": {        "endCursor": "TG9jYXRpb246MTgwMDI4OQ==",        "hasNextPage": false,        "hasPreviousPage": false,        "total": 1      }    }  }}

Um array edges vazio significa que nenhuma correspondência foi encontrada. O nó contém o endereço completo, a categoria e o status approved, portanto uma linha de resultado não precisa de uma segunda consulta.

Obter locais por IDs

GET /locations-by-ids retorna o registro completo de cada local de um lote de IDs em base64 em uma única chamada, usando menos requisições do que uma chamada por local. Tanto locais ativos quanto arquivados são encontrados. Retorna um array simples, não uma conexão. Use para obter os registros completos dos IDs de um payload de webhook ou do seu próprio armazenamento.

Parâmetros

NomeEmObrigatórioObservações
idsquerySimArray de IDs em base64 codificado em JSON. Aplique a codificação de URL ao valor inteiro; curl -G --data-urlencode faz isso por você.
By ids
curl -G https://listingsapi.com/api/v4/locations-by-ids \--data-urlencode 'ids=["TG9jYXRpb246MTgwMDI4OQ==","TG9jYXRpb246MTgwMDI5MA=="]' \-H "Authorization: API $LISTINGSAPI_KEY"
JSON
{  "data": {    "getLocationsByIds": [      {        "id": "TG9jYXRpb246MTgwMDI4OQ==",        "databaseId": 1800289,        "storeId": null,        "name": "Jenny Home",        "archived": false,        "archivedAt": null,        "city": "Austin",        "stateIso": "TX",        "countryIso": "US",        "subCategoryId": 1432,        "businessHours": [],        "locationPhotos": [],        "placeActionLinks": [],        "discoveredPlaceActionLinks": []      }    ]  }}

IDs que não existem na sua conta são omitidos silenciosamente, sem gerar um erro. Compare a quantidade retornada com a quantidade enviada para detectar IDs desatualizados.

Obter locais por códigos de loja

GET /locations-by-store-codes faz a busca inversa: encontra os registros completos correspondentes aos seus próprios códigos de loja. Retorna um array simples. Use quando seu sistema de ponto de venda ou cadastro de franquias identifica os locais pelo código da loja e você nunca armazenou nossos IDs.

Parâmetros

NomeEmObrigatórioObservações
storeCodesquerySimArray de strings de códigos de loja codificado em JSON. Aplique a codificação de URL ao valor inteiro.
By store codes
curl -G https://listingsapi.com/api/v4/locations-by-store-codes \--data-urlencode 'storeCodes=["ACME01","ACME02"]' \-H "Authorization: API $LISTINGSAPI_KEY"
JSON
{  "data": {    "getLocationsByStoreCodes": [      {        "id": "TG9jYXRpb246MTgwMDI4OQ==",        "databaseId": 1800289,        "storeId": "ACME01",        "name": "Jenny Home",        "archived": false,        "city": "Austin",        "countryIso": "US",        "planName": "Launch"      }    ]  }}

Associe o storeId de cada objeto à entrada correspondente no seu cadastro. Códigos sem correspondência não são incluídos. Um local só tem um código de loja se storeId tiver sido definido na criação ou atualização.

Criar um local

POST /locations cria um local e o coloca na fila para envio a todas as plataformas de publicação do seu plano, ou apenas a enabledSiteIds quando você fornece esse campo. Todos os campos ficam dentro de input. 10 campos são obrigatórios; os demais são opcionais, e as plataformas de publicação exibem em branco os que você omitir.

Parâmetros

NomeEmObrigatórioObservações
input.namebodySimNome da empresa, de 2 a 150 caracteres.
input.descriptionbodySimMínimo de 200 caracteres (SY10005). As plataformas de publicação usam esse conteúdo como texto da listagem.
input.countryIsobodySimUm código de país compatível (SY10036). Obtido em países.
input.citybodySimObrigatório quando o hasCity do país é true (SY10126). Quando é false, a cidade que você enviar será descartada.
input.subCategoryIdbodySimdatabaseId numérico obtido em subcategorias.
input.streetbodySimDe 5 a 100 caracteres (SY10011).
input.stateIsobodySimObrigatório quando o stateRequired do país é true, e deve ser um dos valores de states desse país (SY10010). Omita quando stateRequired for false.
input.phonebodySimValidado de acordo com o país (SY10015).
input.postalCodebodyNãoOpcional, mas envie sempre que o hasPostalCode do país for true. O valor que você enviar deve corresponder ao formato do país (SY10014).
input.bizUrlbodySimPublicado como o site. Algumas plataformas de publicação recusam uma listagem sem site.
input.storeIdbodyNãoSeu próprio código de loja, único em toda a conta.
input.businessHoursbodyNão7 entradas de { day, type, slots }. type é OPEN ou CLOSED; um dia sem expediente tem slots vazio.
input.placeActionLinksbodyNãoLinks de ação do Google: placeActionType, uri, isPreferred opcional. action não é necessário na criação. Consulte Links de ação do local.
input.enabledSiteIdsbodyNãoPublique em um subconjunto dos sites do seu plano. IDs obtidos em sites do plano.
input.clientMutationIdbodyNãoRetornado sem alterações para correlação. Não impede gravações duplicadas.

Além dos campos opcionais listados na página de referência: categorias GCID do Google, URLs de redes sociais, coordenadas, contato do proprietário, formas de pagamento, área de atendimento e outros.

Create
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,    "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 }    ]  }}'
JSON
{  "data": {    "createLocation": {      "clientMutationId": null,      "success": true,      "errors": null,      "location": {        "id": "TG9jYXRpb246MTgwMDI5MA==",        "databaseId": 1800290,        "storeId": "ACME01",        "name": "Acme Kitchen",        "city": "New York",        "countryIso": "US",        "status": "PENDING",        "placeActionLinks": [          { "placeActionType": "FOOD_ORDERING", "uri": "https://order.acmekitchen.example.com", "isPreferred": true, "name": null, "submissionStatus": null }        ],        "discoveredPlaceActionLinks": []      }    }  }}

Guarde ambos os IDs: o id em base64 é necessário em todas as gravações posteriores, e databaseId é o número que você vê nos painéis e webhooks. status começa como PENDING e avança sem uma nova chamada à API. O name e o submissionStatus de um link de ação do local permanecem como null até que ele seja sincronizado com o Google. O locations.add() do Python valida os campos obrigatórios localmente e lança ValidationError antes de qualquer chamada de rede; locations.create(input) recebe um dict camelCase bruto em vez disso.

Atualizar um local

POST /locations/update é uma atualização parcial: input.id é o único campo obrigatório e apenas os campos que você envia são alterados. A mesma chamada corrige um número de telefone ou reescreve a programação semanal. Tanto locations.update() do Python quanto updateLocation() do Node recebem um objeto camelCase.

Parâmetros

NomeEmObrigatórioObservações
input.idbodySimO id em base64 do local. O campo é id, não locationId.
input.phone, input.bizUrl, input.name, campos de endereçobodyNãoQualquer campo gravável da chamada de criação.
input.businessHoursbodyNãoEnvie todos os sete dias; uma semana parcial é rejeitada. Adicione entradas day: "SPECIAL" com um specialDate para substituir os horários em feriados, junto com a semana, nunca no lugar dela.
input.moreHoursbodyNãoProgramações secundárias, como entrega, cada uma { hoursTypeId, moreHour }. Não use specialDate aqui.
input.temporarilyClosedbodyNãotrue interrompe a publicação dos horários enquanto o local está fechado.
input.primaryGbpSiteCategoryId, input.additionalGbpSiteCategoryIdsbodyNãoCategorias do Google como GCIDs, por exemplo, gcid:restaurant. Envie countryIso junto com elas.
input.placeActionLinksbodyNãoAdicionar ou inserir/atualizar: cada item recebe action add (padrão) ou delete. Os links que você não mencionar permanecem inalterados.
input.submissionDisabledSiteIdsbodyNãoIds de sites a excluir do envio.

Além dos campos opcionais listados na página de referência.

Update
curl -X POST https://listingsapi.com/api/v4/locations/update \-H "Authorization: API $LISTINGSAPI_KEY" \-H "Content-Type: application/json" \-d '{  "input": {    "id": "TG9jYXRpb246MTgwMDI4OQ==",    "phone": "5125550199",    "bizUrl": "https://acmekitchen.example.com",    "primaryGbpSiteCategoryId": "gcid: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": [] }    ]  }}'
JSON
{  "data": {    "updateLocation": {      "clientMutationId": null,      "success": true,      "errors": null,      "location": {        "id": "TG9jYXRpb246MTgwMDI4OQ==",        "databaseId": 1800289,        "name": "Jenny Home",        "phone": "5125550199",        "status": "APPROVED",        "placeActionLinks": [          { "placeActionType": "FOOD_ORDERING", "uri": "https://order.example.com", "isPreferred": true, "name": null, "submissionStatus": null }        ],        "discoveredPlaceActionLinks": []      }    }  }}

A resposta retorna o local atualizado para que você possa confirmar que os novos valores foram aplicados. Toda atualização retorna o conjunto placeActionLinks atual completo do local. Para alterar a URL de um link, envie um delete para o link antigo e um add para o novo na mesma solicitação.

Arquivar locais

POST /locations/archive agenda o arquivamento de um ou mais locais. O arquivamento não é imediato: cada local entra em ARCHIVE_SCHEDULED, permanece ativo e sujeito a cobrança até o fim do ciclo de cobrança atual e é arquivado quando a próxima fatura é gerada. Use essa chamada para desativar filiais fechadas em lote.

Parâmetros

NomeEmObrigatórioObservações
input.locationIdsbodySimArray de ids em base64 a arquivar.
input.clientMutationIdbodyNãoRetornado sem alterações. Não impede gravações duplicadas.
Archive
curl -X POST https://listingsapi.com/api/v4/locations/archive \-H "Authorization: API $LISTINGSAPI_KEY" \-H "Content-Type: application/json" \-d '{  "input": {    "locationIds": ["TG9jYXRpb246MTgwMDI4OQ==", "TG9jYXRpb246MTgwMDI5MA=="]  }}'
JSON
{  "data": {    "archiveLocations": {      "clientMutationId": null,      "bulkEditTaskId": null,      "errors": null,      "success": null,      "result": [        { "locationId": "TG9jYXRpb246MTgwMDI4OQ==", "status": "ARCHIVE_SCHEDULED", "success": true, "errors": null },        { "locationId": "TG9jYXRpb246MTgwMDI5MA==", "status": "ARCHIVE_SCHEDULED", "success": true, "errors": null }      ]    }  }}

O success de nível superior é null; leia o próprio success de cada entrada de result[], para que um id inválido não bloqueie o restante do lote.

result[].statusSignificado
ARCHIVE_SCHEDULEDNa fila. O local permanece ativo e sujeito a cobrança até o fim do ciclo de cobrança.
ARCHIVEDJá arquivado por uma chamada ou um ciclo anterior.

Enquanto o arquivamento estiver agendado, o archivalScheduledAt do local fica definido nos resultados de listagem e pesquisa. Um local arquivado não pode ser atualizado até ser reativado.

Cancelar o arquivamento agendado

POST /locations/cancel_archive retorna os locais em ARCHIVE_SCHEDULED para ACTIVE, e a cobrança continua. Isso só funciona enquanto o ciclo de cobrança ainda está aberto; depois que um local é totalmente arquivado, essa chamada retorna 404 para ele.

Parâmetros

NomeEmObrigatórioObservações
input.locationIdsbodySimArray de ids em base64 atualmente em ARCHIVE_SCHEDULED.
input.clientMutationIdbodyNãoRetornado sem alterações.
Cancel archive
curl -X POST https://listingsapi.com/api/v4/locations/cancel_archive \-H "Authorization: API $LISTINGSAPI_KEY" \-H "Content-Type: application/json" \-d '{ "input": { "locationIds": ["TG9jYXRpb246MTgwMDI4OQ=="] } }'
JSON
{  "data": {    "cancelLocationsArchive": {      "clientMutationId": null,      "bulkEditTaskId": null,      "errors": null,      "success": null,      "result": [        { "locationId": "TG9jYXRpb246MTgwMDI4OQ==", "status": "ACTIVE", "success": true, "errors": null }      ]    }  }}

Cada entrada de result[] confirma que o local voltou para ACTIVE. Ambos os SDKs exigem dois argumentos posicionais extras, um tipo de seleção e um identificador changedBy, que enviam junto com locationIds; o corpo REST precisa apenas dos ids.

Enviar fotos para um local

POST /locations/photos anexa imagens por URL pública: você hospeda a imagem, e a API a busca e armazena. Um local mantém um LOGO, um COVER e qualquer quantidade de fotos ADDITIONAL. Enviar novamente um logotipo ou uma capa substitui o existente.

Parâmetros

NomeEmObrigatórioObservações
input.locationIdbodySimO id em base64 do local.
input.photosbodySimArray de objetos de imagem; não pode estar vazio.
input.photos[].photobodySimUma URL pública de uma imagem JPEG ou PNG. O campo é photo, não url.
input.photos[].typebodyNãoLOGO, COVER ou ADDITIONAL. O padrão é uma foto adicional.
input.photos[].starredbodyNãoMarque a foto com uma estrela assim que ela chegar. Apenas fotos adicionais, no máximo 4 por local.
input.photos[].sourcebodyNãoRótulo de texto livre que registra a origem da imagem.
Upload
curl -X POST https://listingsapi.com/api/v4/locations/photos \-H "Authorization: API $LISTINGSAPI_KEY" \-H "Content-Type: application/json" \-d '{  "input": {    "locationId": "TG9jYXRpb246MTgwMDI4OQ==",    "photos": [      { "photo": "https://cdn.example.com/jenny-home/logo.png", "type": "LOGO" },      { "photo": "https://cdn.example.com/jenny-home/storefront.jpg", "type": "ADDITIONAL" }    ]  }}'
JSON
{  "data": {    "addLocationPhotos": {      "clientMutationId": null,      "success": true,      "request": {},      "photos": [        { "id": "TWVkaWFGaWxlOjU4Nzg5MzE=", "databaseId": 5878931, "type": "LOGO", "starred": false,          "url": "https://sy-media-store.s3-us-west-2.amazonaws.com/f868bb3f/59c670a3/f47d62a6.png" },        { "id": "TWVkaWFGaWxlOjU4Nzg5MzI=", "databaseId": 5878932, "type": "ADDITIONAL", "starred": false,          "url": "https://sy-media-store.s3-us-west-2.amazonaws.com/f868bb3f/59c670a3/ef4ffb12.jpg" }      ],      "errors": null    }  }}

Guarde o id de cada foto; os endpoints de marcação com estrela e remoção o recebem. Esse é o formato da resposta direta para um lote pequeno. Um lote grande é colocado na fila: photos retorna vazio e request.requestId é definido, e você consulta periodicamente o próximo endpoint com esse id. O limite é uma configuração do servidor, portanto, escolha o fluxo conforme a presença de request.requestId.

Verificar o status do upload de fotos em lote

GET /locations/photos/requests/{requestId} consulta periodicamente um upload na fila até que ele seja concluído e, então, informa o resultado de cada imagem. Use-o para atualizar uma barra de progresso e mostrar exatamente quais arquivos foram rejeitados e por quê.

Parâmetros

NomeEmObrigatórioObservações
requestIdpathSimO UUID de request.requestId na resposta de um upload na fila. Consulte apenas os ids retornados por um upload recente.
Upload status
curl https://listingsapi.com/api/v4/locations/photos/requests/e6c2d9d9-9a18-4015-88cf-9a4e19a6f49a \-H "Authorization: API $LISTINGSAPI_KEY"
JSON
{  "data": {    "getLocationPhotosUploadStatus": {      "requestId": "e6c2d9d9-9a18-4015-88cf-9a4e19a6f49a",      "status": "SUCCESS",      "photos": [        { "mediaId": "TWVkaWFGaWxlOjkxODI3", "locationId": "TG9jYXRpb246MTgwMDI4OQ==", "status": "SUCCESS", "errorMessage": null },        { "mediaId": null, "locationId": "TG9jYXRpb246MTgwMDI4OQ==", "status": "ERROR", "errorMessage": "Image dimensions below the minimum 250x250." }      ]    }  }}
status da tarefaSignificado
PROCESSINGAinda em processamento. Consulte novamente após alguns segundos.
SUCCESSO processamento terminou. Algumas fotos ainda podem ter falhado, então leia photos[].status e photos[].errorMessage.
ERRORA própria tarefa falhou. Inspecione photos[].errorMessage.

O status da tarefa indica apenas que o processamento terminou, não que todas as imagens foram adicionadas. Aguarde alguns segundos entre as consultas; um loop sem intervalo aqui pode fazer você atingir 429 rapidamente.

Obter fotos de um local

GET /locations/{locationId}/photos retorna todos os arquivos de mídia de um local como um array simples: logotipo, capa e imagens adicionais, cada um com seu url público, thumbnailUrl, categoria, flag starred e viewsCount de todo o período. Faça essa chamada antes de um upload para ver qual espaço está vazio e coletar ids para as chamadas de marcação com estrela e remoção.

Parâmetros

NomeEmObrigatórioObservações
locationIdpathSimO id em base64. O databaseId numérico sem codificação também é aceito. Um valor que não esteja em nenhum desses formatos retorna HTTP 200 com SY90002: Invalid Id em errors.
List photos
curl https://listingsapi.com/api/v4/locations/TG9jYXRpb246MTgwMDI4OQ==/photos \-H "Authorization: API $LISTINGSAPI_KEY"
JSON
{  "data": {    "mediaFilesOfLocation": [      { "id": "TWVkaWFGaWxlOjU4Nzg5MzE=", "categoryName": "Logo", "categoryId": "4", "fileType": "image", "starred": false, "viewsCount": 0,        "url": "https://sy-media-store.s3-us-west-2.amazonaws.com/f868bb3f/59c670a3/f47d62a6.jpg",        "thumbnailUrl": "https://sy-media-store.s3-us-west-2.amazonaws.com/f868bb3f/59c670a3/thumbnail_f47d62a6.jpg" },      { "id": "TWVkaWFGaWxlOjU4Nzg5MzI=", "categoryName": "Additional", "categoryId": "12", "fileType": "image", "starred": true, "viewsCount": 143,        "url": "https://sy-media-store.s3-us-west-2.amazonaws.com/f868bb3f/59c670a3/ef4ffb12.jpg",        "thumbnailUrl": "https://sy-media-store.s3-us-west-2.amazonaws.com/f868bb3f/59c670a3/thumbnail_ef4ffb12.jpg" }    ]  }}

categoryName é Logo, Cover ou Additional. Use thumbnailUrl para uma grade e url para a visualização em tamanho original. Um local sem mídia retorna um array vazio, não um erro.

Marcar fotos do local com estrela

POST /locations/photos/star marca fotos adicionais para posicionamento prioritário em plataformas de publicação que oferecem suporte a imagens em destaque. Apenas fotos ADDITIONAL podem ser marcadas com estrela, no máximo 4 por local. A remoção da estrela funciona da mesma forma: a flag starred no corpo determina o que acontece.

Parâmetros

NomeEmObrigatórioObservações
input.locationIdbodySimO id do local em base64.
input.photoIdsbodySimIds de mídia da resposta de get-photos ou do upload.
input.starredbodySimtrue para marcar com estrela, false para remover a estrela. Essa flag, e não o caminho, determina a ação; /star e /unstar se comportam da mesma forma.
Star
curl -X POST https://listingsapi.com/api/v4/locations/photos/star \-H "Authorization: API $LISTINGSAPI_KEY" \-H "Content-Type: application/json" \-d '{  "input": {    "locationId": "TG9jYXRpb246MTgwMDI4OQ==",    "photoIds": ["TWVkaWFGaWxlOjU4Nzg5MzI="],    "starred": true  }}'
JSON
{  "data": {    "starUnstarLocationPhotos": {      "success": true,      "photos": [        { "id": "TWVkaWFGaWxlOjU4Nzg5MzI=", "databaseId": 5878932, "type": "ADDITIONAL", "starred": true }      ],      "error": null    }  }}

A chave da resposta é starUnstarLocationPhotos em ambos os caminhos e contém um único error, não um array errors. Uma quinta foto marcada com estrela faz a chamada inteira falhar com SY15012; a verificação conta as fotos já marcadas com estrela mais as desta requisição.

Remover fotos de um local

POST /locations/photos/remove desvincula fotos adicionais pelo id de mídia. Use-o para retirar imagens desatualizadas da fachada ou desfazer uma importação em lote incorreta. Apenas fotos ADDITIONAL podem ser removidas; substitua um logotipo ou uma capa fazendo o upload de uma nova imagem com esse type.

Parâmetros

NomeEmObrigatórioObservações
input.locationIdbodySimO id do local em base64.
input.photoIdsbodySimIds de mídia a desvincular, obtidos da resposta de get-photos ou do upload.
Remove
curl -X POST https://listingsapi.com/api/v4/locations/photos/remove \-H "Authorization: API $LISTINGSAPI_KEY" \-H "Content-Type: application/json" \-d '{  "input": {    "locationId": "TG9jYXRpb246MTgwMDI4OQ==",    "photoIds": ["TWVkaWFGaWxlOjU4Nzg5MzI="]  }}'
JSON
{  "data": {    "removeLocationPhotos": {      "clientMutationId": null,      "removedCount": 1,      "errors": null    }  }}

removedCount informa quantos arquivos foram efetivamente desvinculados, então 0 com errors: null significa que nenhum desses ids estava vinculado a este local. A remoção desvincula o arquivo; ela não necessariamente o exclui da sua biblioteca de mídia.

Erros que você encontrará

CódigoSignificadoCorreção
SY10005description ausente ou com menos de 200 caracteres na criação.Escreva uma descrição mais completa.
SY10011street ausente ou com menos de 5 caracteres.Envie street.
SY10010stateIso ausente ou inválido para o país.Envie um código de estado obtido em países.
SY10036countryIso não é um país com suporte.Use um código de países.
SY10126city ausente para um país que o exige.Envie city.
SY15012Mais de 4 fotos marcadas com estrela em um local.Remova a estrela de uma delas primeiro ou retire starred do upload.
SY90002Id inválido no caminho de fotos.Informe o id em base64 ou o número sem codificação, não outro formato.
SY90016Uma chave Read foi usada em uma operação de escrita.Use uma chave Write.
HTTP 404Cancelamento do arquivamento de um local que não está mais em ARCHIVE_SCHEDULED.O local está totalmente arquivado; use o fluxo de reativação.
HTTP 429Limite de requisições excedido.Aguarde Retry-After. Consulte limites de requisições.

Operações de escrita também podem retornar HTTP 200 com success: false e os detalhes em data.<operation>.errors. A lista completa está em códigos de erro.

Próximos passos