Contas conectadas
Todos os endpoints: exemplos cURL, Python e Node; conectar Google/Facebook, listar contas, associar e vincular listagens, pastas, criar GMB e desconectar.
Uma conta conectada é uma autorização OAuth concedida pelo proprietário de um Google Business Profile ou de páginas do Facebook que permite à API ler e gerenciar as listagens às quais essa conta tem acesso. O recurso abrange três tarefas: criar os links OAuth, encontrar correspondências ou vincular as listagens da conta aos seus locais e desfazer a conexão. As duas operações de leitura GET, de lista e de detalhes, funcionam com uma chave Read (leitura); toda operação POST, inclusive a busca de listagens somente para leitura, exige uma chave Write (escrita), e o uso de uma chave Read em uma operação de escrita retorna HTTP 400 com SY90016.
Todos os exemplos abaixo pressupõem um cliente criado uma única vez, como mostra o primeiro exemplo, e leem LISTINGSAPI_KEY do ambiente. Os IDs são o UUID connectedAccountId do endpoint de listagem e o ID do local em base64 (TG9jYXRpb246MTgwMDI4OQ==); nunca aplique codificação de URL a nenhum deles.
Visão geral dos endpoints
Criar um link de conexão com o Google
POST /connected-accounts/connect-google
Retorna uma URL OAuth de curta duração. Redirecione o proprietário da conta para ela; o Google o redireciona de volta para successUrl ou errorUrl que você informou. O link é restrito à conta à qual pertence a chave de API, portanto o corpo contém apenas suas duas URLs de redirecionamento. Emitir novamente um link para uma conta cuja autorização expirou atualiza a conexão existente em vez de duplicá-la.
curl -X POST https://listingsapi.com/api/v4/connected-accounts/connect-google \-H "Authorization: API $LISTINGSAPI_KEY" \-H "Content-Type: application/json" \-d '{ "input": { "successUrl": "https://app.example.com/connect/google/success", "errorUrl": "https://app.example.com/connect/google/error" }}'{ "data": { "bulkConnectLinkForGoogle": { "success": true, "url": "https://connect.example.com/oauth?token=8f3c1d92-...", "errors": null } }}O valor url acima é ilustrativo. Direcione o proprietário para o valor de url retornado na resposta que você recebeu.
O link é válido por 24 horas. errors só é preenchido quando a geração falha, portanto verifique se url não é nulo. Um corpo sem aninhamento, ou que contenha accountId, é rejeitado com HTTP 400.
Criar um link de conexão com o Facebook
POST /connected-accounts/connect-facebook
É o equivalente para o Facebook, com o mesmo corpo. Durante o fluxo, o proprietário aceita os termos do Facebook e concede as permissões de gerenciamento de páginas de que a API precisa; se ele deixar de conceder uma permissão, a conexão não poderá sincronizar, portanto emita o link novamente e peça que ele dê o consentimento outra vez.
curl -X POST https://listingsapi.com/api/v4/connected-accounts/connect-facebook \-H "Authorization: API $LISTINGSAPI_KEY" \-H "Content-Type: application/json" \-d '{ "input": { "successUrl": "https://app.example.com/connect/facebook/success", "errorUrl": "https://app.example.com/connect/facebook/error" }}'{ "data": { "bulkConnectLinkForFacebook": { "success": true, "url": "https://connect.example.com/oauth?token=8f3c1d92-...", "errors": null } }}O valor url acima é ilustrativo. Direcione o proprietário para o valor de url retornado na resposta que você recebeu.
A chave da resposta é bulkConnectLinkForFacebook; quanto ao restante, interprete a resposta exatamente como a do link do Google. Assim que o proprietário concluir o fluxo, a conta aparecerá no endpoint de listagem como FacebookAccount.
Criar um link de conexão para um local
POST /locations/oauth_connect_url
Use esta opção quando você já souber qual local o proprietário está conectando. O link fica vinculado ao local que você especificar, portanto não há uma etapa de correspondência depois: quando o proprietário der consentimento, as credenciais serão associadas diretamente a esse local. Já os dois links em massa acima conectam uma conta inteira.
curl -X POST https://listingsapi.com/api/v4/locations/oauth_connect_url \-H "Authorization: API $LISTINGSAPI_KEY" \-H "Content-Type: application/json" \-d '{ "input": { "locationId": "TG9jYXRpb246MTgwMDI4OQ==", "site": "GOOGLE", "successUrl": "https://app.example.com/locations/1800289/connected", "errorUrl": "https://app.example.com/locations/1800289/connect-failed" }}'{ "data": { "createConnectUrl": { "success": true, "url": "https://connect.example.com/oauth?token=8f3c1d92-...", "errors": null } }}O url acima é um valor de exemplo. Direcione o proprietário para o url retornado na resposta à sua própria requisição.
O link só pode ser usado uma vez, portanto crie um novo a cada tentativa em vez de armazená-lo em cache. Uma URL de redirecionamento relativa ou que não possa ser interpretada resulta em success: true com null url, portanto verifique url e não apenas success. Uma chave sem permissão para acessar esse local recebe um 403 com SY90003. Os SDKs convertem site para maiúsculas para você.
Listar contas conectadas
GET /connected-accounts
Retorna todas as contas autorizadas na sua conta da API, com o estado da conexão e a quantidade de locais vinculados a cada uma. Esta é uma página com paginação por deslocamento: records[] mais pageInfo.totalRecords, paginada pelos parâmetros de consulta page e perPage, sem aninhamento. A ordenação é fixa, pelo e-mail da conta em ordem crescente.
curl "https://listingsapi.com/api/v4/connected-accounts?publisher=GoogleAccount&status=Connected&page=1&perPage=20" \-H "Authorization: API $LISTINGSAPI_KEY"{ "data": { "connectedAccountsInfo": { "pageInfo": { "hasNextPage": false, "hasPreviousPage": false, "totalPages": 1, "totalRecords": 1 }, "records": [ { "connectedAccountId": "4f712c17-4f95-42dd-90f4-97171a2e67b5", "connectedAccountType": "GoogleAccount", "email": "owner@brightsmile-dental.com", "status": "CONNECTED", "connectivityIssue": null, "connectedLocationsCount": 0, "requestMatchesStatus": "MATCH_COMPLETED", "lastFetchMatchesRequestedAt": "2026-07-06 21:43:07 UTC" } ] } }}Selecione o registro cujo email corresponde ao proprietário que deu consentimento e guarde seu connectedAccountId; todas as chamadas posteriores usam esse valor. Tudo além dos quatro parâmetros de consulta é ignorado em vez de rejeitado, portanto um pageInfo em JSON retorna a página 1 sem aviso.
O filtro status e o campo status do registro não usam o mesmo conjunto de valores. Reutilizar CONNECTED como filtro fornece um valor inválido para o enum e resulta em um 400.
Obter os detalhes de uma conta
GET /connected-accounts/{connectedAccountId}/details
Retorna os mesmos campos de um registro da lista, com escopo restrito a uma conta. Use esta opção para consultar periodicamente requestMatchesStatus após iniciar a busca de correspondências ou para verificar status e connectivityIssue antes de enviar uma atualização por meio da conta.
curl https://listingsapi.com/api/v4/connected-accounts/4f712c17-4f95-42dd-90f4-97171a2e67b5/details \-H "Authorization: API $LISTINGSAPI_KEY"{ "data": { "connectedAccountDetails": { "details": { "connectedAccountId": "4f712c17-4f95-42dd-90f4-97171a2e67b5", "connectedAccountType": "GoogleAccount", "status": "CONNECTED", "connectivityIssue": null, "connectedLocationsCount": 0, "requestMatchesStatus": "MATCH_COMPLETED" } } }}O registro está um nível abaixo, em data.connectedAccountDetails.details. requestMatchesStatus passa de MATCH_IN_PROGRESS para MATCH_COMPLETED quando as sugestões estão prontas. Concluído significa que o processo de busca de correspondências terminou, não que algo esteja vinculado: connectedLocationsCount permanece como 0 até você confirmar ou conectar uma listagem.
Buscar as listagens que uma conta pode acessar
POST /connected-accounts/connected-account-listings
Lista todas as listagens do Google Business Profile ou do Facebook às quais a conta tem acesso, estejam ou não vinculadas a um dos seus locais. O id de cada registro é o connectedAccountListingId usado por connect-listing e create-location-from-listing. Esta é uma operação POST somente de leitura e retorna uma página com paginação por deslocamento: records[] mais pageInfo, paginada pelas chaves page e perPage no corpo, sem aninhamento.
curl -X POST https://listingsapi.com/api/v4/connected-accounts/connected-account-listings \-H "Authorization: API $LISTINGSAPI_KEY" \-H "Content-Type: application/json" \-d '{ "connectedAccountId": "4f712c17-4f95-42dd-90f4-97171a2e67b5", "perPage": 50, "locationInfo": "William St" }'{ "data": { "connectedAccountListings": { "pageInfo": { "hasNextPage": false, "totalPages": 1, "totalRecords": 60 }, "records": [ { "id": "R21iQnVsa0RhdGFMYWtlOjA2MDQ4NmExLTA0NzQtNDc4NS1iMjNhLTBkOGM4MzhmNGQ5OA==", "accountTypeName": "Google", "locationName": "Trial", "address": "123 William St, NY 10038, Manhattan, US", "phone": "(718) 667-7787", "liveLink": null } ] } }}Percorra as páginas do conjunto com pageInfo.hasNextPage e pageInfo.totalPages. Os SDKs colocam connectedAccountId no corpo para você, portanto isso afeta apenas chamadas REST escritas manualmente.
Iniciar a correspondência
POST /connected-accounts/trigger-matches
Coloca na fila o job que recupera todos os perfis acessíveis às contas especificadas e associa cada um a um dos seus locais. A correspondência considera todos os locais ativos, não arquivados e ainda não conectados. Ela grava apenas sugestões; nada é vinculado até que você confirme.
curl -X POST https://listingsapi.com/api/v4/connected-accounts/trigger-matches \-H "Authorization: API $LISTINGSAPI_KEY" \-H "Content-Type: application/json" \-d '{ "input": { "connectedAccountIds": ["4f712c17-4f95-42dd-90f4-97171a2e67b5"] } }'{ "data": { "connectedAccountsTriggerMatches": { "success": true, "failedIds": null } }}success: true significa que o job foi colocado na fila, não que a correspondência foi concluída. Qualquer conta que não pôde ser colocada na fila aparece em failedIds, e success é false. Consulte periodicamente o endpoint de detalhes até que requestMatchesStatus seja MATCH_COMPLETED antes de ler as sugestões; consultas a cada 15 segundos em um loop com limite de iterações mantêm o plano Launch dentro do limite de 10 requisições por minuto.
Ler sugestões de conexão
GET /connected-accounts/{connectedAccountId}/connection-suggestions
Retorna as associações propostas pelo processo de correspondência: seu local de um lado (locationInfo, com locationId como seu databaseId) e a listagem na plataforma de publicação do outro (suggestedLocationInfo). A paginação é baseada em offset e usa os parâmetros de consulta page e perPage sem aninhamento; a ordenação é fixa, em ordem crescente pelas informações do local.
curl "https://listingsapi.com/api/v4/connected-accounts/4f712c17-4f95-42dd-90f4-97171a2e67b5/connection-suggestions?page=1&perPage=20" \-H "Authorization: API $LISTINGSAPI_KEY"{ "data": { "connectionSuggestionsForAccount": { "pageInfo": { "hasNextPage": false, "totalPages": 1, "totalRecords": 2 }, "records": [ { "accountType": "GMB", "matchedDataDatabaseId": "0d5e306f-0da0-46e3-929f-fd3c67ccd8cc", "connectedAccountId": "4f712c17-4f95-42dd-90f4-97171a2e67b5", "locationId": "73415", "locationInfo": { "name": "My Business", "city": "Lincoln", "stateIso": "NE" }, "suggestedLocationInfo": { "locationInfo": { "name": "My Business", "city": "Lincoln" } } } ] } }}Uma sugestão não tem id. Mantenha matchedDataDatabaseId e accountType juntos; confirm-matches precisa de ambos para montar seu id. Se você consultar cedo demais, antes de MATCH_COMPLETED, o endpoint retornará records: [] com totalRecords: 0, um resultado idêntico ao de "nenhuma correspondência encontrada".
Confirmar correspondências
POST /connected-accounts/confirm-matches
Aceita as sugestões que você aprova e cria os vínculos ativos. Cada id é a codificação em base64 de <MatchRecordType>:<matchedDataDatabaseId>, com o tipo escolhido na tabela acima. A conta é inferida a partir dos registros, portanto não há campo connectedAccountId; um campo desconhecido dentro de input é rejeitado com status 400.
# base64 of GmbLocationMatchedData:0d5e306f-0da0-46e3-929f-fd3c67ccd8cccurl -X POST https://listingsapi.com/api/v4/connected-accounts/confirm-matches \-H "Authorization: API $LISTINGSAPI_KEY" \-H "Content-Type: application/json" \-d '{ "input": { "matchRecordIds": ["R21iTG9jYXRpb25NYXRjaGVkRGF0YTowZDVlMzA2Zi0wZGEwLTQ2ZTMtOTI5Zi1mZDNjNjdjY2Q4Y2M="] } }'{ "data": { "confirmConnectMatches": { "success": true, "failedIds": null } }}failedIds contém os valores decodificados de matchedDataDatabaseId que não puderam ser confirmados, como um registro já consumido ou um local arquivado após a correspondência, portanto associe esses valores aos respectivos registros de sugestão. As sugestões não enviadas permanecem inalteradas. A confirmação vincula o local à listagem; ela não envia dados à plataforma de publicação por si só.
Conectar uma listagem a um local
POST /connected-accounts/connect-listing
Vincula uma única listagem que você já escolheu a um único local, sem etapa de sugestão ou confirmação. Use quando a correspondência for ambígua, por exemplo, quando houver duas lojas próximas com nomes semelhantes e um operador escolher a correta entre as listagens da conta.
curl -X POST https://listingsapi.com/api/v4/connected-accounts/connect-listing \-H "Authorization: API $LISTINGSAPI_KEY" \-H "Content-Type: application/json" \-d '{ "input": { "locationId": "TG9jYXRpb246MTgwMDI4OQ==", "connectedAccountId": "4f712c17-4f95-42dd-90f4-97171a2e67b5", "connectedAccountListingId": "R21iQnVsa0RhdGFMYWtlOjA2MDQ4NmExLTA0NzQtNDc4NS1iMjNhLTBkOGM4MzhmNGQ5OA==" }}'{ "data": { "connectListing": { "success": true, "message": null } }}Uma tentativa de vinculação malsucedida retorna success: false com message não nulo, por exemplo, Listing record not found quando o id da listagem não corresponde a nenhuma listagem, ou uma observação de que a listagem já está conectada a outro local. Nos dois SDKs, esse método fica no recurso de listagens, não no de contas conectadas.
Desconectar uma listagem de um local
POST /connected-accounts/disconnect-listing
Remove o vínculo entre um local e uma plataforma de publicação. O local e seus dados são mantidos; apenas a sincronização de saída para essa plataforma de publicação é interrompida. Este endpoint não processa operações em lote, portanto percorra os locais em um loop. Para vincular uma loja a outra conta do Google, desconecte-a aqui primeiro e depois faça a correspondência ou a conexão na nova conta.
curl -X POST https://listingsapi.com/api/v4/connected-accounts/disconnect-listing \-H "Authorization: API $LISTINGSAPI_KEY" \-H "Content-Type: application/json" \-d '{ "input": { "locationId": "TG9jYXRpb246MTgwMDI4OQ==", "site": "GOOGLE" } }'{ "data": { "disconnectConnectedAccountsLocations": { "clientMutationId": null, "success": true, "errors": null } }}Se você não enviar nem site nem providerId, o endpoint retornará SY10056. Para um local sem conexão ativa com esse site, o endpoint retorna SY10057 em vez de indicar sucesso silenciosamente, portanto success: true de fato significa que um vínculo foi removido. Os SDKs aceitam apenas site e o convertem para letras maiúsculas.
Criar um local a partir de uma listagem
POST /connected-accounts/create-location-from-listing
A correspondência apenas associa listagens a locais que você já tem. Para uma listagem sem local, esta operação cria um local com os dados da plataforma de publicação e o vincula à listagem de uma só vez. O Google importa nome, endereço, coordenadas, telefone, site, descrição, horários regulares e especiais, categorias, data de abertura, código da loja e fuso horário, além de formas de pagamento e links de redes sociais derivados dos atributos da listagem no Google. O Facebook importa nome, local, horários, categorias, descrição e informações de contato.
Em uma importação do Google, os dados não são reenviados ao Google, então a listagem permanece em IN_PROGRESS até que a primeira atualização do local seja publicada nela. O envio para todas as outras plataformas de publicação ocorre normalmente, e este endpoint não aceita um escopo de sites, portanto o local é criado para o conjunto completo de plataformas de publicação da sua conta. Restrinja esse conjunto com enabledSiteIds logo após a criação e envie essa atualização imediatamente: os itens de pedido para as outras plataformas de publicação são gerados pouco depois da criação, e a atualização não retira os que já foram gerados.
Nenhum dos dois SDKs oferece um método para este endpoint ainda, então os exemplos em Python e Node fazem chamadas REST com o mesmo cabeçalho.
curl -X POST https://listingsapi.com/api/v4/connected-accounts/create-location-from-listing \-H "Authorization: API $LISTINGSAPI_KEY" \-H "Content-Type: application/json" \-d '{ "input": { "connectedAccountId": "4f712c17-4f95-42dd-90f4-97171a2e67b5", "connectedAccountListingId": "R21iQnVsa0RhdGFMYWtlOjA2MDQ4NmExLTA0NzQtNDc4NS1iMjNhLTBkOGM4MzhmNGQ5OA==" }}'{ "data": { "createLocationFromConnectedAccountListing": { "success": true, "locationId": 88277, "errors": null } }}locationId é o databaseId simples do novo local. Em caso de falha, success é false, locationId é null e errors contém um código que indica o motivo, como SY81067 (o id da listagem não foi encontrado); outras causas são uma listagem já vinculada a outro local ou uma conta cujas credenciais expiraram. Após a criação, gerencie o local como qualquer outro.
Listar as pastas de uma conta do Google
GET /connected-accounts/{connectedAccountId}/folders
Retorna os grupos de contas (pastas) do Google Business Profile aos quais a conta do Google conectada tem acesso. Use este endpoint antes de criar uma listagem do GMB para que o novo perfil seja criado no grupo esperado pelo proprietário. A resposta é um array simples em getFoldersUnderGoogleAccount, não uma página. O caminho só é válido para conexões GoogleAccount.
curl https://listingsapi.com/api/v4/connected-accounts/4f712c17-4f95-42dd-90f4-97171a2e67b5/folders \-H "Authorization: API $LISTINGSAPI_KEY"{ "data": { "getFoldersUnderGoogleAccount": [ { "folderId": "accounts/104890024806530350198", "folderName": "Bright Smile Dental", "locationCount": null } ] }}Use folderId sem alterações; esse valor é a string accounts/{id}, não um número. locationCount pode ser null quando o Google não o informa, então trate-o como opcional.
Criar um Google Business Profile para um local
POST /locations/create/gmb-listing
Cria uma nova listagem do Google para um local que não tem nenhuma, em uma conta do Google conectada e, opcionalmente, dentro de uma pasta. Diferentemente de connect-listing, que vincula uma listagem já existente. O local já deve ter nome, endereço e telefone, e só pode existir uma listagem do Google por local.
curl -X POST https://listingsapi.com/api/v4/locations/create/gmb-listing \-H "Authorization: API $LISTINGSAPI_KEY" \-H "Content-Type: application/json" \-d '{ "input": { "locationId": "TG9jYXRpb246MTgwMDI4OQ==", "connectedAccountId": "4f712c17-4f95-42dd-90f4-97171a2e67b5", "folderId": "accounts/104890024806530350198" }}'{ "data": { "createGmbListingForLocation": { "clientMutationId": null, "success": true, "errors": null } }}A criação é assíncrona: success: true significa que a solicitação foi aceita, e o Google analisa os novos perfis antes de serem publicados. Quando success é false, errors informa o motivo: campos obrigatórios ausentes, uma listagem do Google existente, um local arquivado ou uma conta inativa.
Desconectar uma conta inteira do Google
POST /connected-accounts/disconnect-google
Encerra a conexão de toda a conta: todos os locais vinculados por meio dela deixam de sincronizar. Não há um campo locationIds; para desvincular um local e manter a conta, use disconnect-listing. Use esta operação quando um cliente sair ou quando não for possível remover uma autorização com falha e você quiser recomeçar com um novo link de conexão.
curl -X POST https://listingsapi.com/api/v4/connected-accounts/disconnect-google \-H "Authorization: API $LISTINGSAPI_KEY" \-H "Content-Type: application/json" \-d '{ "input": { "connectedAccountId": "d2397854-52c2-41d7-95f1-b90cba16498d" } }'{ "data": { "gmbBulkDisconnect": { "success": true } }}success: true é retornado mesmo para um connectedAccountId desconhecido, portanto significa "a solicitação foi processada", e não "uma conexão ativa foi removida". Liste as contas conectadas novamente se precisar confirmar.
Desconectar uma conta inteira do Facebook
POST /connected-accounts/disconnect-facebook
A operação equivalente para o Facebook, com o mesmo corpo. As páginas vinculadas por meio da conta deixam de sincronizar e as interações do Facebook deixam de aparecer.
curl -X POST https://listingsapi.com/api/v4/connected-accounts/disconnect-facebook \-H "Authorization: API $LISTINGSAPI_KEY" \-H "Content-Type: application/json" \-d '{ "input": { "connectedAccountId": "d2397854-52c2-41d7-95f1-b90cba16498d" } }'{ "data": { "fbBulkDisconnect": { "success": true } }}A chave da resposta é fbBulkDisconnect. Assim como no Google, success: true para um id desconhecido significa que a solicitação foi processada, não que uma conexão foi removida.
Desconectar um local de uma plataforma de publicação
POST /locations/oauth-disconnect
A etapa de desconexão do fluxo OAuth por local. É a mesma operação que disconnect-listing, disponível em um segundo caminho: corpo input idêntico e a mesma chave de resposta disconnectConnectedAccountsLocations. Escolha o caminho que ficar mais claro na sua integração.
curl -X POST https://listingsapi.com/api/v4/locations/oauth-disconnect \-H "Authorization: API $LISTINGSAPI_KEY" \-H "Content-Type: application/json" \-d '{ "input": { "locationId": "TG9jYXRpb246MTgwMDI4OQ==", "site": "GOOGLE" } }'{ "data": { "disconnectConnectedAccountsLocations": { "clientMutationId": null, "success": true, "errors": null } }}As mesmas regras de SY10056 e SY10057 se aplicam, e uma chave sem permissão para operar neste local recebe um 403 com SY90003. A desconexão mantém o local e seus dados intactos; apenas a sincronização de saída para essa plataforma de publicação é interrompida. Encaminhe o proprietário novamente para a URL de conexão, ou execute a busca de correspondências e connect-listing, para vincular a listagem correta depois.
Erros que você pode encontrar
Solicitações malformadas e chaves inválidas retornam um 4xx com um errors[] no nível superior cujo message começa com o código. As operações de escrita também podem retornar 200 com success: false e o motivo em data.<operation>, portanto verifique o corpo da resposta de cada operação de escrita. A lista completa está em Códigos de erro.
Próximas etapas
- Conectar o Google e importar locais: o fluxo em lote do Google do início ao fim, com consultas periódicas e eventos de webhook.
- Conectar páginas do Facebook: o mesmo fluxo para o Facebook, incluindo a desconexão da conta.
- Criar um Google Business Profile: pastas e criação de GMB para um local sem listagem no Google.
- Verificar o status das listagens e os links ativos: acompanhe a mudança da linha do Google para
SYNCEDapós o vínculo ser estabelecido. - Índice de referência: Contas conectadas; páginas dos SDKs: Contas conectadas em Python, Contas conectadas em Node, Listagens em Python, Listagens em Node.